Skip to content

Commit 4ee508f

Browse files
committed
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== 100GbE Intel Wired LAN Driver Updates 2022-03-03 Jacob Keller says: This series refactors the ice networking driver VF storage from a simple static array to a hash table. It also introduces krefs and proper locking and protection to prevent common use-after-free and concurrency issues. There are two motivations for this work. First is to make the ice driver more resilient by preventing a whole class of use-after-free bugs that can occur around concurrent access to VF structures while removing VFs. The second is to prepare the ice driver for future virtualization work to support Scalable IOV, an alternative VF implementation compared to Single Root IOV. The new VF implementation will allow for more dynamic VF creation and removal, necessitating a more robust implementation for VF storage that can't rely on the existing mechanisms to prevent concurrent access violations. The first few patches are cleanup and preparatory work needed to make the conversion to the hash table safe. Following this preparatory work is a patch to migrate the VF structures and variables to a new sub-structure for code clarity. Next introduce new interface functions to abstract the VF storage. Finally, the driver is actually converted to the hash table and kref implementation. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f2ecfa0 + 3d5985a commit 4ee508f

File tree

13 files changed

+872
-554
lines changed

13 files changed

+872
-554
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@
109109
/* All VF control VSIs share the same IRQ, so assign a unique ID for them */
110110
#define ICE_RES_VF_CTRL_VEC_ID (ICE_RES_RDMA_VEC_ID - 1)
111111
#define ICE_INVAL_Q_INDEX 0xffff
112-
#define ICE_INVAL_VFID 256
113112

114113
#define ICE_MAX_RXQS_PER_TC 256 /* Used when setting VSI context per TC Rx queues */
115114

@@ -333,7 +332,7 @@ struct ice_vsi {
333332
u16 vsi_num; /* HW (absolute) index of this VSI */
334333
u16 idx; /* software index in pf->vsi[] */
335334

336-
s16 vf_id; /* VF ID for SR-IOV VSIs */
335+
struct ice_vf *vf; /* VF associated with this VSI */
337336

338337
u16 ethtype; /* Ethernet protocol for pause frame */
339338
u16 num_gfltr;
@@ -529,15 +528,7 @@ struct ice_pf {
529528
struct ice_vsi **vsi; /* VSIs created by the driver */
530529
struct ice_sw *first_sw; /* first switch created by firmware */
531530
u16 eswitch_mode; /* current mode of eswitch */
532-
/* Virtchnl/SR-IOV config info */
533-
struct ice_vf *vf;
534-
u16 num_alloc_vfs; /* actual number of VFs allocated */
535-
u16 num_vfs_supported; /* num VFs supported for this PF */
536-
u16 num_qps_per_vf;
537-
u16 num_msix_per_vf;
538-
/* used to ratelimit the MDD event logging */
539-
unsigned long last_printed_mdd_jiffies;
540-
DECLARE_BITMAP(malvfs, ICE_MAX_VF_COUNT);
531+
struct ice_vfs vfs;
541532
DECLARE_BITMAP(features, ICE_F_MAX);
542533
DECLARE_BITMAP(state, ICE_STATE_NBITS);
543534
DECLARE_BITMAP(flags, ICE_PF_FLAGS_NBITS);

drivers/net/ethernet/intel/ice/ice_base.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ ice_setup_tx_ctx(struct ice_tx_ring *ring, struct ice_tlan_ctx *tlan_ctx, u16 pf
323323
break;
324324
case ICE_VSI_VF:
325325
/* Firmware expects vmvf_num to be absolute VF ID */
326-
tlan_ctx->vmvf_num = hw->func_caps.vf_base_id + vsi->vf_id;
326+
tlan_ctx->vmvf_num = hw->func_caps.vf_base_id + vsi->vf->vf_id;
327327
tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_VF;
328328
break;
329329
case ICE_VSI_SWITCHDEV_CTRL:
@@ -429,7 +429,7 @@ static int ice_setup_rx_ctx(struct ice_rx_ring *ring)
429429
*/
430430
if (ice_is_dvm_ena(hw))
431431
if (vsi->type == ICE_VSI_VF &&
432-
ice_vf_is_port_vlan_ena(&vsi->back->vf[vsi->vf_id]))
432+
ice_vf_is_port_vlan_ena(vsi->vf))
433433
rlan_ctx.l2tsel = 1;
434434
else
435435
rlan_ctx.l2tsel = 0;

drivers/net/ethernet/intel/ice/ice_eswitch.c

Lines changed: 94 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,20 @@ static void ice_eswitch_remap_rings_to_vectors(struct ice_pf *pf)
176176
int q_id;
177177

178178
ice_for_each_txq(vsi, q_id) {
179-
struct ice_repr *repr = pf->vf[q_id].repr;
180-
struct ice_q_vector *q_vector = repr->q_vector;
181-
struct ice_tx_ring *tx_ring = vsi->tx_rings[q_id];
182-
struct ice_rx_ring *rx_ring = vsi->rx_rings[q_id];
179+
struct ice_q_vector *q_vector;
180+
struct ice_tx_ring *tx_ring;
181+
struct ice_rx_ring *rx_ring;
182+
struct ice_repr *repr;
183+
struct ice_vf *vf;
184+
185+
vf = ice_get_vf_by_id(pf, q_id);
186+
if (WARN_ON(!vf))
187+
continue;
188+
189+
repr = vf->repr;
190+
q_vector = repr->q_vector;
191+
tx_ring = vsi->tx_rings[q_id];
192+
rx_ring = vsi->rx_rings[q_id];
183193

184194
q_vector->vsi = vsi;
185195
q_vector->reg_idx = vsi->q_vectors[0]->reg_idx;
@@ -199,6 +209,38 @@ static void ice_eswitch_remap_rings_to_vectors(struct ice_pf *pf)
199209
rx_ring->q_vector = q_vector;
200210
rx_ring->next = NULL;
201211
rx_ring->netdev = repr->netdev;
212+
213+
ice_put_vf(vf);
214+
}
215+
}
216+
217+
/**
218+
* ice_eswitch_release_reprs - clear PR VSIs configuration
219+
* @pf: poiner to PF struct
220+
* @ctrl_vsi: pointer to switchdev control VSI
221+
*/
222+
static void
223+
ice_eswitch_release_reprs(struct ice_pf *pf, struct ice_vsi *ctrl_vsi)
224+
{
225+
struct ice_vf *vf;
226+
unsigned int bkt;
227+
228+
lockdep_assert_held(&pf->vfs.table_lock);
229+
230+
ice_for_each_vf(pf, bkt, vf) {
231+
struct ice_vsi *vsi = vf->repr->src_vsi;
232+
233+
/* Skip VFs that aren't configured */
234+
if (!vf->repr->dst)
235+
continue;
236+
237+
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
238+
metadata_dst_free(vf->repr->dst);
239+
vf->repr->dst = NULL;
240+
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr.addr,
241+
ICE_FWD_TO_VSI);
242+
243+
netif_napi_del(&vf->repr->q_vector->napi);
202244
}
203245
}
204246

@@ -210,11 +252,13 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
210252
{
211253
struct ice_vsi *ctrl_vsi = pf->switchdev.control_vsi;
212254
int max_vsi_num = 0;
213-
int i;
255+
struct ice_vf *vf;
256+
unsigned int bkt;
257+
258+
lockdep_assert_held(&pf->vfs.table_lock);
214259

215-
ice_for_each_vf(pf, i) {
216-
struct ice_vsi *vsi = pf->vf[i].repr->src_vsi;
217-
struct ice_vf *vf = &pf->vf[i];
260+
ice_for_each_vf(pf, bkt, vf) {
261+
struct ice_vsi *vsi = vf->repr->src_vsi;
218262

219263
ice_remove_vsi_fltr(&pf->hw, vsi->idx);
220264
vf->repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
@@ -231,6 +275,7 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
231275
vf->hw_lan_addr.addr,
232276
ICE_FWD_TO_VSI);
233277
metadata_dst_free(vf->repr->dst);
278+
vf->repr->dst = NULL;
234279
goto err;
235280
}
236281

@@ -239,6 +284,7 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
239284
vf->hw_lan_addr.addr,
240285
ICE_FWD_TO_VSI);
241286
metadata_dst_free(vf->repr->dst);
287+
vf->repr->dst = NULL;
242288
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
243289
goto err;
244290
}
@@ -252,8 +298,8 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
252298
netif_keep_dst(vf->repr->netdev);
253299
}
254300

255-
ice_for_each_vf(pf, i) {
256-
struct ice_repr *repr = pf->vf[i].repr;
301+
ice_for_each_vf(pf, bkt, vf) {
302+
struct ice_repr *repr = vf->repr;
257303
struct ice_vsi *vsi = repr->src_vsi;
258304
struct metadata_dst *dst;
259305

@@ -266,42 +312,11 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
266312
return 0;
267313

268314
err:
269-
for (i = i - 1; i >= 0; i--) {
270-
struct ice_vsi *vsi = pf->vf[i].repr->src_vsi;
271-
struct ice_vf *vf = &pf->vf[i];
272-
273-
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
274-
metadata_dst_free(vf->repr->dst);
275-
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr.addr,
276-
ICE_FWD_TO_VSI);
277-
}
315+
ice_eswitch_release_reprs(pf, ctrl_vsi);
278316

279317
return -ENODEV;
280318
}
281319

282-
/**
283-
* ice_eswitch_release_reprs - clear PR VSIs configuration
284-
* @pf: poiner to PF struct
285-
* @ctrl_vsi: pointer to switchdev control VSI
286-
*/
287-
static void
288-
ice_eswitch_release_reprs(struct ice_pf *pf, struct ice_vsi *ctrl_vsi)
289-
{
290-
int i;
291-
292-
ice_for_each_vf(pf, i) {
293-
struct ice_vsi *vsi = pf->vf[i].repr->src_vsi;
294-
struct ice_vf *vf = &pf->vf[i];
295-
296-
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
297-
metadata_dst_free(vf->repr->dst);
298-
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr.addr,
299-
ICE_FWD_TO_VSI);
300-
301-
netif_napi_del(&vf->repr->q_vector->napi);
302-
}
303-
}
304-
305320
/**
306321
* ice_eswitch_update_repr - reconfigure VF port representor
307322
* @vsi: VF VSI for which port representor is configured
@@ -316,15 +331,16 @@ void ice_eswitch_update_repr(struct ice_vsi *vsi)
316331
if (!ice_is_switchdev_running(pf))
317332
return;
318333

319-
vf = &pf->vf[vsi->vf_id];
334+
vf = vsi->vf;
320335
repr = vf->repr;
321336
repr->src_vsi = vsi;
322337
repr->dst->u.port_info.port_id = vsi->vsi_num;
323338

324339
ret = ice_vsi_update_security(vsi, ice_vsi_ctx_clear_antispoof);
325340
if (ret) {
326341
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr.addr, ICE_FWD_TO_VSI);
327-
dev_err(ice_pf_to_dev(pf), "Failed to update VF %d port representor", vsi->vf_id);
342+
dev_err(ice_pf_to_dev(pf), "Failed to update VF %d port representor",
343+
vsi->vf->vf_id);
328344
}
329345
}
330346

@@ -408,7 +424,7 @@ static void ice_eswitch_release_env(struct ice_pf *pf)
408424
static struct ice_vsi *
409425
ice_eswitch_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
410426
{
411-
return ice_vsi_setup(pf, pi, ICE_VSI_SWITCHDEV_CTRL, ICE_INVAL_VFID, NULL);
427+
return ice_vsi_setup(pf, pi, ICE_VSI_SWITCHDEV_CTRL, NULL, NULL);
412428
}
413429

414430
/**
@@ -417,10 +433,13 @@ ice_eswitch_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
417433
*/
418434
static void ice_eswitch_napi_del(struct ice_pf *pf)
419435
{
420-
int i;
436+
struct ice_vf *vf;
437+
unsigned int bkt;
421438

422-
ice_for_each_vf(pf, i)
423-
netif_napi_del(&pf->vf[i].repr->q_vector->napi);
439+
lockdep_assert_held(&pf->vfs.table_lock);
440+
441+
ice_for_each_vf(pf, bkt, vf)
442+
netif_napi_del(&vf->repr->q_vector->napi);
424443
}
425444

426445
/**
@@ -429,10 +448,13 @@ static void ice_eswitch_napi_del(struct ice_pf *pf)
429448
*/
430449
static void ice_eswitch_napi_enable(struct ice_pf *pf)
431450
{
432-
int i;
451+
struct ice_vf *vf;
452+
unsigned int bkt;
453+
454+
lockdep_assert_held(&pf->vfs.table_lock);
433455

434-
ice_for_each_vf(pf, i)
435-
napi_enable(&pf->vf[i].repr->q_vector->napi);
456+
ice_for_each_vf(pf, bkt, vf)
457+
napi_enable(&vf->repr->q_vector->napi);
436458
}
437459

438460
/**
@@ -441,10 +463,13 @@ static void ice_eswitch_napi_enable(struct ice_pf *pf)
441463
*/
442464
static void ice_eswitch_napi_disable(struct ice_pf *pf)
443465
{
444-
int i;
466+
struct ice_vf *vf;
467+
unsigned int bkt;
468+
469+
lockdep_assert_held(&pf->vfs.table_lock);
445470

446-
ice_for_each_vf(pf, i)
447-
napi_disable(&pf->vf[i].repr->q_vector->napi);
471+
ice_for_each_vf(pf, bkt, vf)
472+
napi_disable(&vf->repr->q_vector->napi);
448473
}
449474

450475
/**
@@ -522,7 +547,7 @@ ice_eswitch_mode_set(struct devlink *devlink, u16 mode,
522547
if (pf->eswitch_mode == mode)
523548
return 0;
524549

525-
if (pf->num_alloc_vfs) {
550+
if (ice_has_vfs(pf)) {
526551
dev_info(ice_pf_to_dev(pf), "Changing eswitch mode is allowed only if there is no VFs created");
527552
NL_SET_ERR_MSG_MOD(extack, "Changing eswitch mode is allowed only if there is no VFs created");
528553
return -EOPNOTSUPP;
@@ -613,16 +638,17 @@ int ice_eswitch_configure(struct ice_pf *pf)
613638
*/
614639
static void ice_eswitch_start_all_tx_queues(struct ice_pf *pf)
615640
{
616-
struct ice_repr *repr;
617-
int i;
641+
struct ice_vf *vf;
642+
unsigned int bkt;
643+
644+
lockdep_assert_held(&pf->vfs.table_lock);
618645

619646
if (test_bit(ICE_DOWN, pf->state))
620647
return;
621648

622-
ice_for_each_vf(pf, i) {
623-
repr = pf->vf[i].repr;
624-
if (repr)
625-
ice_repr_start_tx_queues(repr);
649+
ice_for_each_vf(pf, bkt, vf) {
650+
if (vf->repr)
651+
ice_repr_start_tx_queues(vf->repr);
626652
}
627653
}
628654

@@ -632,16 +658,17 @@ static void ice_eswitch_start_all_tx_queues(struct ice_pf *pf)
632658
*/
633659
void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf)
634660
{
635-
struct ice_repr *repr;
636-
int i;
661+
struct ice_vf *vf;
662+
unsigned int bkt;
663+
664+
lockdep_assert_held(&pf->vfs.table_lock);
637665

638666
if (test_bit(ICE_DOWN, pf->state))
639667
return;
640668

641-
ice_for_each_vf(pf, i) {
642-
repr = pf->vf[i].repr;
643-
if (repr)
644-
ice_repr_stop_tx_queues(repr);
669+
ice_for_each_vf(pf, bkt, vf) {
670+
if (vf->repr)
671+
ice_repr_stop_tx_queues(vf->repr);
645672
}
646673
}
647674

drivers/net/ethernet/intel/ice/ice_ethtool.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -316,16 +316,20 @@ ice_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
316316
*/
317317
static bool ice_active_vfs(struct ice_pf *pf)
318318
{
319-
unsigned int i;
320-
321-
ice_for_each_vf(pf, i) {
322-
struct ice_vf *vf = &pf->vf[i];
319+
bool active = false;
320+
struct ice_vf *vf;
321+
unsigned int bkt;
323322

324-
if (test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
325-
return true;
323+
rcu_read_lock();
324+
ice_for_each_vf_rcu(pf, bkt, vf) {
325+
if (test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
326+
active = true;
327+
break;
328+
}
326329
}
330+
rcu_read_unlock();
327331

328-
return false;
332+
return active;
329333
}
330334

331335
/**
@@ -1298,7 +1302,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
12981302
}
12991303

13001304
if (test_bit(ICE_FLAG_VF_VLAN_PRUNING, change_flags) &&
1301-
pf->num_alloc_vfs) {
1305+
ice_has_vfs(pf)) {
13021306
dev_err(dev, "vf-vlan-pruning: VLAN pruning cannot be changed while VFs are active.\n");
13031307
/* toggle bit back to previous state */
13041308
change_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags);

0 commit comments

Comments
 (0)