Skip to content

Commit 0fb1d8e

Browse files
pgardocxkuba-moo
authored andcommitted
iavf: fix potential races for FDIR filters
Add fdir_fltr_lock locking in unprotected places. The change in iavf_fdir_is_dup_fltr adds a spinlock around a loop which iterates over all filters and looks for a duplicate. The filter can be removed from list and freed from memory at the same time it's being compared. All other places where filters are deleted are already protected with spinlock. The remaining changes protect adapter->fdir_active_fltr variable so now all its uses are under a spinlock. Fixes: 527691b ("iavf: Support IPv4 Flow Director filters") Signed-off-by: Piotr Gardocki <piotrx.gardocki@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://lore.kernel.org/r/20230807205011.3129224-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 06b4125 commit 0fb1d8e

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

drivers/net/ethernet/intel/iavf/iavf_ethtool.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1401,14 +1401,15 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
14011401
if (fsp->flow_type & FLOW_MAC_EXT)
14021402
return -EINVAL;
14031403

1404+
spin_lock_bh(&adapter->fdir_fltr_lock);
14041405
if (adapter->fdir_active_fltr >= IAVF_MAX_FDIR_FILTERS) {
1406+
spin_unlock_bh(&adapter->fdir_fltr_lock);
14051407
dev_err(&adapter->pdev->dev,
14061408
"Unable to add Flow Director filter because VF reached the limit of max allowed filters (%u)\n",
14071409
IAVF_MAX_FDIR_FILTERS);
14081410
return -ENOSPC;
14091411
}
14101412

1411-
spin_lock_bh(&adapter->fdir_fltr_lock);
14121413
if (iavf_find_fdir_fltr_by_loc(adapter, fsp->location)) {
14131414
dev_err(&adapter->pdev->dev, "Failed to add Flow Director filter, it already exists\n");
14141415
spin_unlock_bh(&adapter->fdir_fltr_lock);
@@ -1781,7 +1782,9 @@ static int iavf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
17811782
case ETHTOOL_GRXCLSRLCNT:
17821783
if (!FDIR_FLTR_SUPPORT(adapter))
17831784
break;
1785+
spin_lock_bh(&adapter->fdir_fltr_lock);
17841786
cmd->rule_cnt = adapter->fdir_active_fltr;
1787+
spin_unlock_bh(&adapter->fdir_fltr_lock);
17851788
cmd->data = IAVF_MAX_FDIR_FILTERS;
17861789
ret = 0;
17871790
break;

drivers/net/ethernet/intel/iavf/iavf_fdir.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,9 @@ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *f
722722
bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr)
723723
{
724724
struct iavf_fdir_fltr *tmp;
725+
bool ret = false;
725726

727+
spin_lock_bh(&adapter->fdir_fltr_lock);
726728
list_for_each_entry(tmp, &adapter->fdir_list_head, list) {
727729
if (tmp->flow_type != fltr->flow_type)
728730
continue;
@@ -732,11 +734,14 @@ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *
732734
!memcmp(&tmp->ip_data, &fltr->ip_data,
733735
sizeof(fltr->ip_data)) &&
734736
!memcmp(&tmp->ext_data, &fltr->ext_data,
735-
sizeof(fltr->ext_data)))
736-
return true;
737+
sizeof(fltr->ext_data))) {
738+
ret = true;
739+
break;
740+
}
737741
}
742+
spin_unlock_bh(&adapter->fdir_fltr_lock);
738743

739-
return false;
744+
return ret;
740745
}
741746

742747
/**

0 commit comments

Comments
 (0)