Skip to content

Commit

Permalink
i40evf: protect VLAN filter list
Browse files Browse the repository at this point in the history
The MAC filter list is protected by a critical task bit, and the VLAN
list should be protected as well. This prevents list corruption if the
watchdog happens to run at the same time as a VLAN filter is being added
or deleted.

Change-ID: Ia4867cebbbb046a1f38012771b288a634ca5882b
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Tested-by: Jim Young <james.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Mitch Williams authored and Jeff Kirsher committed Apr 3, 2015
1 parent fdf0e0b commit 13acb54
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions drivers/net/ethernet/intel/i40evf/i40evf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,13 +664,21 @@ i40evf_vlan_filter *i40evf_find_vlan(struct i40evf_adapter *adapter, u16 vlan)
static struct
i40evf_vlan_filter *i40evf_add_vlan(struct i40evf_adapter *adapter, u16 vlan)
{
struct i40evf_vlan_filter *f;
struct i40evf_vlan_filter *f = NULL;
int count = 50;

while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section)) {
udelay(1);
if (--count == 0)
goto out;
}

f = i40evf_find_vlan(adapter, vlan);
if (!f) {
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
return NULL;
goto clearout;

f->vlan = vlan;

Expand All @@ -680,6 +688,9 @@ i40evf_vlan_filter *i40evf_add_vlan(struct i40evf_adapter *adapter, u16 vlan)
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
}

clearout:
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
out:
return f;
}

Expand All @@ -691,12 +702,21 @@ i40evf_vlan_filter *i40evf_add_vlan(struct i40evf_adapter *adapter, u16 vlan)
static void i40evf_del_vlan(struct i40evf_adapter *adapter, u16 vlan)
{
struct i40evf_vlan_filter *f;
int count = 50;

while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section)) {
udelay(1);
if (--count == 0)
return;
}

f = i40evf_find_vlan(adapter, vlan);
if (f) {
f->remove = true;
adapter->aq_required |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
}
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
}

/**
Expand Down

0 comments on commit 13acb54

Please sign in to comment.