Commit 53a9e346 authored by Jedrzej Jagielski's avatar Jedrzej Jagielski Committed by Tony Nguyen
Browse files

i40e: Fix race condition while adding/deleting MAC/VLAN filters



There was a race condition in access to hw->aq.asq_last_status
while adding and deleting  MAC/VLAN filters causing
incorrect error status to be printed as ERROR OK instead of
the correct error.

Change calls to i40e_aq_add_macvlan in i40e_aqc_add_filters
and i40e_aq_remove_macvlan in i40e_aqc_del_filters
to  _v2 versions that return Admin Queue status on the stack
to avoid race conditions in access to hw->aq.asq_last_status.

Signed-off-by: default avatarSylwester Dziedziuch <sylwesterx.dziedziuch@intel.com>
Signed-off-by: default avatarJedrzej Jagielski <jedrzej.jagielski@intel.com>
Tested-by: default avatarGurucharan G <gurucharanx.g@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent b3237df9
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -2143,19 +2143,19 @@ void i40e_aqc_del_filters(struct i40e_vsi *vsi, const char *vsi_name,
			  int num_del, int *retval)
{
	struct i40e_hw *hw = &vsi->back->hw;
	enum i40e_admin_queue_err aq_status;
	i40e_status aq_ret;
	int aq_err;

	aq_ret = i40e_aq_remove_macvlan(hw, vsi->seid, list, num_del, NULL);
	aq_err = hw->aq.asq_last_status;
	aq_ret = i40e_aq_remove_macvlan_v2(hw, vsi->seid, list, num_del, NULL,
					   &aq_status);

	/* Explicitly ignore and do not report when firmware returns ENOENT */
	if (aq_ret && !(aq_err == I40E_AQ_RC_ENOENT)) {
	if (aq_ret && !(aq_status == I40E_AQ_RC_ENOENT)) {
		*retval = -EIO;
		dev_info(&vsi->back->pdev->dev,
			 "ignoring delete macvlan error on %s, err %s, aq_err %s\n",
			 vsi_name, i40e_stat_str(hw, aq_ret),
			 i40e_aq_str(hw, aq_err));
			 i40e_aq_str(hw, aq_status));
	}
}

@@ -2178,10 +2178,10 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
			  int num_add)
{
	struct i40e_hw *hw = &vsi->back->hw;
	int aq_err, fcnt;
	enum i40e_admin_queue_err aq_status;
	int fcnt;

	i40e_aq_add_macvlan(hw, vsi->seid, list, num_add, NULL);
	aq_err = hw->aq.asq_last_status;
	i40e_aq_add_macvlan_v2(hw, vsi->seid, list, num_add, NULL, &aq_status);
	fcnt = i40e_update_filter_state(num_add, list, add_head);

	if (fcnt != num_add) {
@@ -2189,17 +2189,19 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
			set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
			dev_warn(&vsi->back->pdev->dev,
				 "Error %s adding RX filters on %s, promiscuous mode forced on\n",
				 i40e_aq_str(hw, aq_err), vsi_name);
				 i40e_aq_str(hw, aq_status), vsi_name);
		} else if (vsi->type == I40E_VSI_SRIOV ||
			   vsi->type == I40E_VSI_VMDQ1 ||
			   vsi->type == I40E_VSI_VMDQ2) {
			dev_warn(&vsi->back->pdev->dev,
				 "Error %s adding RX filters on %s, please set promiscuous on manually for %s\n",
				 i40e_aq_str(hw, aq_err), vsi_name, vsi_name);
				 i40e_aq_str(hw, aq_status), vsi_name,
					     vsi_name);
		} else {
			dev_warn(&vsi->back->pdev->dev,
				 "Error %s adding RX filters on %s, incorrect VSI type: %i.\n",
				 i40e_aq_str(hw, aq_err), vsi_name, vsi->type);
				 i40e_aq_str(hw, aq_status), vsi_name,
					     vsi->type);
		}
	}
}