Skip to content

Commit adacf21

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== iavf: fix racing in VLANs Ahmed Zaki says: This patchset mainly fixes a racing issue in the iavf where the number of VLANs in the vlan_filter_list might be more than the PF limit. To fix that, we get rid of the cvlans and svlans bitmaps and keep all the required info in the list. The second patch adds two new states that are needed so that we keep the VLAN info while the interface goes DOWN: -- DISABLE (notify PF, but keep the filter in the list) -- INACTIVE (dev is DOWN, filter is removed from PF) Finally, the current code keeps each state in a separate bit field, which is error prone. The first patch refactors that by replacing all bits with a single enum. The changes are minimal where each bit change is replaced with the new state value. * '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: iavf: remove active_cvlans and active_svlans bitmaps iavf: refactor VLAN filter states ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 160c131 + 9c85b7f commit adacf21

File tree

3 files changed

+66
-66
lines changed

3 files changed

+66
-66
lines changed

drivers/net/ethernet/intel/iavf/iavf.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ enum iavf_vsi_state_t {
5959
struct iavf_vsi {
6060
struct iavf_adapter *back;
6161
struct net_device *netdev;
62-
unsigned long active_cvlans[BITS_TO_LONGS(VLAN_N_VID)];
63-
unsigned long active_svlans[BITS_TO_LONGS(VLAN_N_VID)];
6462
u16 seid;
6563
u16 id;
6664
DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
@@ -158,15 +156,20 @@ struct iavf_vlan {
158156
u16 tpid;
159157
};
160158

159+
enum iavf_vlan_state_t {
160+
IAVF_VLAN_INVALID,
161+
IAVF_VLAN_ADD, /* filter needs to be added */
162+
IAVF_VLAN_IS_NEW, /* filter is new, wait for PF answer */
163+
IAVF_VLAN_ACTIVE, /* filter is accepted by PF */
164+
IAVF_VLAN_DISABLE, /* filter needs to be deleted by PF, then marked INACTIVE */
165+
IAVF_VLAN_INACTIVE, /* filter is inactive, we are in IFF_DOWN */
166+
IAVF_VLAN_REMOVE, /* filter needs to be removed from list */
167+
};
168+
161169
struct iavf_vlan_filter {
162170
struct list_head list;
163171
struct iavf_vlan vlan;
164-
struct {
165-
u8 is_new_vlan:1; /* filter is new, wait for PF answer */
166-
u8 remove:1; /* filter needs to be removed */
167-
u8 add:1; /* filter needs to be added */
168-
u8 padding:5;
169-
};
172+
enum iavf_vlan_state_t state;
170173
};
171174

172175
#define IAVF_MAX_TRAFFIC_CLASS 4
@@ -258,6 +261,7 @@ struct iavf_adapter {
258261
wait_queue_head_t vc_waitqueue;
259262
struct iavf_q_vector *q_vectors;
260263
struct list_head vlan_filter_list;
264+
int num_vlan_filters;
261265
struct list_head mac_filter_list;
262266
struct mutex crit_lock;
263267
struct mutex client_lock;

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

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,8 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter,
791791
f->vlan = vlan;
792792

793793
list_add_tail(&f->list, &adapter->vlan_filter_list);
794-
f->add = true;
794+
f->state = IAVF_VLAN_ADD;
795+
adapter->num_vlan_filters++;
795796
adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
796797
}
797798

@@ -813,7 +814,7 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)
813814

814815
f = iavf_find_vlan(adapter, vlan);
815816
if (f) {
816-
f->remove = true;
817+
f->state = IAVF_VLAN_REMOVE;
817818
adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
818819
}
819820

@@ -828,14 +829,18 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)
828829
**/
829830
static void iavf_restore_filters(struct iavf_adapter *adapter)
830831
{
831-
u16 vid;
832+
struct iavf_vlan_filter *f;
832833

833834
/* re-add all VLAN filters */
834-
for_each_set_bit(vid, adapter->vsi.active_cvlans, VLAN_N_VID)
835-
iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021Q));
835+
spin_lock_bh(&adapter->mac_vlan_list_lock);
836836

837-
for_each_set_bit(vid, adapter->vsi.active_svlans, VLAN_N_VID)
838-
iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021AD));
837+
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
838+
if (f->state == IAVF_VLAN_INACTIVE)
839+
f->state = IAVF_VLAN_ADD;
840+
}
841+
842+
spin_unlock_bh(&adapter->mac_vlan_list_lock);
843+
adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
839844
}
840845

841846
/**
@@ -844,8 +849,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)
844849
*/
845850
u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
846851
{
847-
return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
848-
bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
852+
return adapter->num_vlan_filters;
849853
}
850854

851855
/**
@@ -928,11 +932,6 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
928932
return 0;
929933

930934
iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)));
931-
if (proto == cpu_to_be16(ETH_P_8021Q))
932-
clear_bit(vid, adapter->vsi.active_cvlans);
933-
else
934-
clear_bit(vid, adapter->vsi.active_svlans);
935-
936935
return 0;
937936
}
938937

@@ -1293,16 +1292,11 @@ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
12931292
}
12941293
}
12951294

1296-
/* remove all VLAN filters */
1295+
/* disable all VLAN filters */
12971296
list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
1298-
list) {
1299-
if (vlf->add) {
1300-
list_del(&vlf->list);
1301-
kfree(vlf);
1302-
} else {
1303-
vlf->remove = true;
1304-
}
1305-
}
1297+
list)
1298+
vlf->state = IAVF_VLAN_DISABLE;
1299+
13061300
spin_unlock_bh(&adapter->mac_vlan_list_lock);
13071301
}
13081302

@@ -2914,6 +2908,7 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
29142908
list_del(&fv->list);
29152909
kfree(fv);
29162910
}
2911+
adapter->num_vlan_filters = 0;
29172912

29182913
spin_unlock_bh(&adapter->mac_vlan_list_lock);
29192914

@@ -3131,9 +3126,6 @@ static void iavf_reset_task(struct work_struct *work)
31313126
adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
31323127
iavf_misc_irq_enable(adapter);
31333128

3134-
bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
3135-
bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
3136-
31373129
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 2);
31383130

31393131
/* We were running when the reset started, so we need to restore some

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

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -642,16 +642,10 @@ static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
642642

643643
spin_lock_bh(&adapter->mac_vlan_list_lock);
644644
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
645-
if (f->is_new_vlan) {
646-
if (f->vlan.tpid == ETH_P_8021Q)
647-
clear_bit(f->vlan.vid,
648-
adapter->vsi.active_cvlans);
649-
else
650-
clear_bit(f->vlan.vid,
651-
adapter->vsi.active_svlans);
652-
645+
if (f->state == IAVF_VLAN_IS_NEW) {
653646
list_del(&f->list);
654647
kfree(f);
648+
adapter->num_vlan_filters--;
655649
}
656650
}
657651
spin_unlock_bh(&adapter->mac_vlan_list_lock);
@@ -679,7 +673,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
679673
spin_lock_bh(&adapter->mac_vlan_list_lock);
680674

681675
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
682-
if (f->add)
676+
if (f->state == IAVF_VLAN_ADD)
683677
count++;
684678
}
685679
if (!count || !VLAN_FILTERING_ALLOWED(adapter)) {
@@ -710,11 +704,10 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
710704
vvfl->vsi_id = adapter->vsi_res->vsi_id;
711705
vvfl->num_elements = count;
712706
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
713-
if (f->add) {
707+
if (f->state == IAVF_VLAN_ADD) {
714708
vvfl->vlan_id[i] = f->vlan.vid;
715709
i++;
716-
f->add = false;
717-
f->is_new_vlan = true;
710+
f->state = IAVF_VLAN_IS_NEW;
718711
if (i == count)
719712
break;
720713
}
@@ -760,7 +753,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
760753
vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
761754
vvfl_v2->num_elements = count;
762755
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
763-
if (f->add) {
756+
if (f->state == IAVF_VLAN_ADD) {
764757
struct virtchnl_vlan_supported_caps *filtering_support =
765758
&adapter->vlan_v2_caps.filtering.filtering_support;
766759
struct virtchnl_vlan *vlan;
@@ -778,8 +771,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
778771
vlan->tpid = f->vlan.tpid;
779772

780773
i++;
781-
f->add = false;
782-
f->is_new_vlan = true;
774+
f->state = IAVF_VLAN_IS_NEW;
783775
}
784776
}
785777

@@ -822,10 +814,16 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
822814
* filters marked for removal to enable bailing out before
823815
* sending a virtchnl message
824816
*/
825-
if (f->remove && !VLAN_FILTERING_ALLOWED(adapter)) {
817+
if (f->state == IAVF_VLAN_REMOVE &&
818+
!VLAN_FILTERING_ALLOWED(adapter)) {
826819
list_del(&f->list);
827820
kfree(f);
828-
} else if (f->remove) {
821+
adapter->num_vlan_filters--;
822+
} else if (f->state == IAVF_VLAN_DISABLE &&
823+
!VLAN_FILTERING_ALLOWED(adapter)) {
824+
f->state = IAVF_VLAN_INACTIVE;
825+
} else if (f->state == IAVF_VLAN_REMOVE ||
826+
f->state == IAVF_VLAN_DISABLE) {
829827
count++;
830828
}
831829
}
@@ -857,11 +855,18 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
857855
vvfl->vsi_id = adapter->vsi_res->vsi_id;
858856
vvfl->num_elements = count;
859857
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
860-
if (f->remove) {
858+
if (f->state == IAVF_VLAN_DISABLE) {
861859
vvfl->vlan_id[i] = f->vlan.vid;
860+
f->state = IAVF_VLAN_INACTIVE;
862861
i++;
862+
if (i == count)
863+
break;
864+
} else if (f->state == IAVF_VLAN_REMOVE) {
865+
vvfl->vlan_id[i] = f->vlan.vid;
863866
list_del(&f->list);
864867
kfree(f);
868+
adapter->num_vlan_filters--;
869+
i++;
865870
if (i == count)
866871
break;
867872
}
@@ -901,7 +906,8 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
901906
vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
902907
vvfl_v2->num_elements = count;
903908
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
904-
if (f->remove) {
909+
if (f->state == IAVF_VLAN_DISABLE ||
910+
f->state == IAVF_VLAN_REMOVE) {
905911
struct virtchnl_vlan_supported_caps *filtering_support =
906912
&adapter->vlan_v2_caps.filtering.filtering_support;
907913
struct virtchnl_vlan *vlan;
@@ -915,8 +921,13 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
915921
vlan->tci = f->vlan.vid;
916922
vlan->tpid = f->vlan.tpid;
917923

918-
list_del(&f->list);
919-
kfree(f);
924+
if (f->state == IAVF_VLAN_DISABLE) {
925+
f->state = IAVF_VLAN_INACTIVE;
926+
} else {
927+
list_del(&f->list);
928+
kfree(f);
929+
adapter->num_vlan_filters--;
930+
}
920931
i++;
921932
if (i == count)
922933
break;
@@ -2192,7 +2203,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
21922203
list_for_each_entry(vlf,
21932204
&adapter->vlan_filter_list,
21942205
list)
2195-
vlf->add = true;
2206+
vlf->state = IAVF_VLAN_ADD;
21962207

21972208
adapter->aq_required |=
21982209
IAVF_FLAG_AQ_ADD_VLAN_FILTER;
@@ -2260,7 +2271,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
22602271
list_for_each_entry(vlf,
22612272
&adapter->vlan_filter_list,
22622273
list)
2263-
vlf->add = true;
2274+
vlf->state = IAVF_VLAN_ADD;
22642275

22652276
aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
22662277
}
@@ -2444,15 +2455,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
24442455

24452456
spin_lock_bh(&adapter->mac_vlan_list_lock);
24462457
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
2447-
if (f->is_new_vlan) {
2448-
f->is_new_vlan = false;
2449-
if (f->vlan.tpid == ETH_P_8021Q)
2450-
set_bit(f->vlan.vid,
2451-
adapter->vsi.active_cvlans);
2452-
else
2453-
set_bit(f->vlan.vid,
2454-
adapter->vsi.active_svlans);
2455-
}
2458+
if (f->state == IAVF_VLAN_IS_NEW)
2459+
f->state = IAVF_VLAN_ACTIVE;
24562460
}
24572461
spin_unlock_bh(&adapter->mac_vlan_list_lock);
24582462
}

0 commit comments

Comments
 (0)