Skip to content

Commit 1f20c77

Browse files
committed
Merge branch '200GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2026-01-06 (idpf) This series contains updates to idpf driver only. Emil fixes issues related to resets; among them timeouts, NULL pointer dereferences, and memory leaks. Sreedevi resolves issues around RSS; mainly involving operations when the interface is down and resets. She also addresses some incomplete cleanups for ntuple filters and interrupts. Erik fixes incomplete output of ntuple filters. Josh sets restriction of Rx buffer size to follow hardware restrictions. Larysa adds check to prevent NULL pointer dereference when RDMA is not enabled. * '200GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: idpf: fix aux device unplugging when rdma is not supported by vport idpf: cap maximum Rx buffer size idpf: Fix error handling in idpf_vport_open() idpf: Fix RSS LUT NULL ptr issue after soft reset idpf: Fix RSS LUT configuration on down interfaces idpf: Fix RSS LUT NULL pointer crash on early ethtool operations idpf: fix issue with ethtool -n command display idpf: fix memory leak of flow steer list on rmmod idpf: fix error handling in the init_task on load idpf: fix memory leak in idpf_vc_core_deinit() idpf: fix memory leak in idpf_vport_rel() idpf: detach and close netdevs while handling a reset idpf: keep the netdev when a reset fails ==================== Link: https://patch.msgid.link/20260107000648.1861994-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 4b5bdab + 4648fb2 commit 1f20c77

7 files changed

Lines changed: 256 additions & 184 deletions

File tree

drivers/net/ethernet/intel/idpf/idpf.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,7 @@ struct idpf_port_stats {
284284

285285
struct idpf_fsteer_fltr {
286286
struct list_head list;
287-
u32 loc;
288-
u32 q_index;
287+
struct ethtool_rx_flow_spec fs;
289288
};
290289

291290
/**
@@ -424,14 +423,12 @@ enum idpf_user_flags {
424423
* @rss_key: RSS hash key
425424
* @rss_lut_size: Size of RSS lookup table
426425
* @rss_lut: RSS lookup table
427-
* @cached_lut: Used to restore previously init RSS lut
428426
*/
429427
struct idpf_rss_data {
430428
u16 rss_key_size;
431429
u8 *rss_key;
432430
u16 rss_lut_size;
433431
u32 *rss_lut;
434-
u32 *cached_lut;
435432
};
436433

437434
/**
@@ -558,13 +555,15 @@ struct idpf_vector_lifo {
558555
* @max_q: Maximum possible queues
559556
* @req_qs_chunks: Queue chunk data for requested queues
560557
* @mac_filter_list_lock: Lock to protect mac filters
558+
* @flow_steer_list_lock: Lock to protect fsteer filters
561559
* @flags: See enum idpf_vport_config_flags
562560
*/
563561
struct idpf_vport_config {
564562
struct idpf_vport_user_config_data user_config;
565563
struct idpf_vport_max_q max_q;
566564
struct virtchnl2_add_queues *req_qs_chunks;
567565
spinlock_t mac_filter_list_lock;
566+
spinlock_t flow_steer_list_lock;
568567
DECLARE_BITMAP(flags, IDPF_VPORT_CONFIG_FLAGS_NBITS);
569568
};
570569

drivers/net/ethernet/intel/idpf/idpf_ethtool.c

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,51 @@ static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
3737
{
3838
struct idpf_netdev_priv *np = netdev_priv(netdev);
3939
struct idpf_vport_user_config_data *user_config;
40+
struct idpf_vport_config *vport_config;
4041
struct idpf_fsteer_fltr *f;
4142
struct idpf_vport *vport;
4243
unsigned int cnt = 0;
4344
int err = 0;
4445

4546
idpf_vport_ctrl_lock(netdev);
4647
vport = idpf_netdev_to_vport(netdev);
47-
user_config = &np->adapter->vport_config[np->vport_idx]->user_config;
48+
vport_config = np->adapter->vport_config[np->vport_idx];
49+
user_config = &vport_config->user_config;
4850

4951
switch (cmd->cmd) {
5052
case ETHTOOL_GRXCLSRLCNT:
5153
cmd->rule_cnt = user_config->num_fsteer_fltrs;
5254
cmd->data = idpf_fsteer_max_rules(vport);
5355
break;
5456
case ETHTOOL_GRXCLSRULE:
55-
err = -EINVAL;
57+
err = -ENOENT;
58+
spin_lock_bh(&vport_config->flow_steer_list_lock);
5659
list_for_each_entry(f, &user_config->flow_steer_list, list)
57-
if (f->loc == cmd->fs.location) {
58-
cmd->fs.ring_cookie = f->q_index;
60+
if (f->fs.location == cmd->fs.location) {
61+
/* Avoid infoleak from padding: zero first,
62+
* then assign fields
63+
*/
64+
memset(&cmd->fs, 0, sizeof(cmd->fs));
65+
cmd->fs = f->fs;
5966
err = 0;
6067
break;
6168
}
69+
spin_unlock_bh(&vport_config->flow_steer_list_lock);
6270
break;
6371
case ETHTOOL_GRXCLSRLALL:
6472
cmd->data = idpf_fsteer_max_rules(vport);
73+
spin_lock_bh(&vport_config->flow_steer_list_lock);
6574
list_for_each_entry(f, &user_config->flow_steer_list, list) {
6675
if (cnt == cmd->rule_cnt) {
6776
err = -EMSGSIZE;
6877
break;
6978
}
70-
rule_locs[cnt] = f->loc;
79+
rule_locs[cnt] = f->fs.location;
7180
cnt++;
7281
}
7382
if (!err)
7483
cmd->rule_cnt = user_config->num_fsteer_fltrs;
84+
spin_unlock_bh(&vport_config->flow_steer_list_lock);
7585
break;
7686
default:
7787
break;
@@ -168,7 +178,7 @@ static int idpf_add_flow_steer(struct net_device *netdev,
168178
struct idpf_vport *vport;
169179
u32 flow_type, q_index;
170180
u16 num_rxq;
171-
int err;
181+
int err = 0;
172182

173183
vport = idpf_netdev_to_vport(netdev);
174184
vport_config = vport->adapter->vport_config[np->vport_idx];
@@ -194,6 +204,29 @@ static int idpf_add_flow_steer(struct net_device *netdev,
194204
if (!rule)
195205
return -ENOMEM;
196206

207+
fltr = kzalloc(sizeof(*fltr), GFP_KERNEL);
208+
if (!fltr) {
209+
err = -ENOMEM;
210+
goto out_free_rule;
211+
}
212+
213+
/* detect duplicate entry and reject before adding rules */
214+
spin_lock_bh(&vport_config->flow_steer_list_lock);
215+
list_for_each_entry(f, &user_config->flow_steer_list, list) {
216+
if (f->fs.location == fsp->location) {
217+
err = -EEXIST;
218+
break;
219+
}
220+
221+
if (f->fs.location > fsp->location)
222+
break;
223+
parent = f;
224+
}
225+
spin_unlock_bh(&vport_config->flow_steer_list_lock);
226+
227+
if (err)
228+
goto out;
229+
197230
rule->vport_id = cpu_to_le32(vport->vport_id);
198231
rule->count = cpu_to_le32(1);
199232
info = &rule->rule_info[0];
@@ -232,26 +265,20 @@ static int idpf_add_flow_steer(struct net_device *netdev,
232265
goto out;
233266
}
234267

235-
fltr = kzalloc(sizeof(*fltr), GFP_KERNEL);
236-
if (!fltr) {
237-
err = -ENOMEM;
238-
goto out;
239-
}
240-
241-
fltr->loc = fsp->location;
242-
fltr->q_index = q_index;
243-
list_for_each_entry(f, &user_config->flow_steer_list, list) {
244-
if (f->loc >= fltr->loc)
245-
break;
246-
parent = f;
247-
}
268+
/* Save a copy of the user's flow spec so ethtool can later retrieve it */
269+
fltr->fs = *fsp;
248270

271+
spin_lock_bh(&vport_config->flow_steer_list_lock);
249272
parent ? list_add(&fltr->list, &parent->list) :
250273
list_add(&fltr->list, &user_config->flow_steer_list);
251274

252275
user_config->num_fsteer_fltrs++;
276+
spin_unlock_bh(&vport_config->flow_steer_list_lock);
277+
goto out_free_rule;
253278

254279
out:
280+
kfree(fltr);
281+
out_free_rule:
255282
kfree(rule);
256283
return err;
257284
}
@@ -302,17 +329,20 @@ static int idpf_del_flow_steer(struct net_device *netdev,
302329
goto out;
303330
}
304331

332+
spin_lock_bh(&vport_config->flow_steer_list_lock);
305333
list_for_each_entry_safe(f, iter,
306334
&user_config->flow_steer_list, list) {
307-
if (f->loc == fsp->location) {
335+
if (f->fs.location == fsp->location) {
308336
list_del(&f->list);
309337
kfree(f);
310338
user_config->num_fsteer_fltrs--;
311-
goto out;
339+
goto out_unlock;
312340
}
313341
}
314-
err = -EINVAL;
342+
err = -ENOENT;
315343

344+
out_unlock:
345+
spin_unlock_bh(&vport_config->flow_steer_list_lock);
316346
out:
317347
kfree(rule);
318348
return err;
@@ -381,18 +411,24 @@ static u32 idpf_get_rxfh_indir_size(struct net_device *netdev)
381411
* @netdev: network interface device structure
382412
* @rxfh: pointer to param struct (indir, key, hfunc)
383413
*
384-
* Reads the indirection table directly from the hardware. Always returns 0.
414+
* RSS LUT and Key information are read from driver's cached
415+
* copy. When rxhash is off, rss lut will be displayed as zeros.
416+
*
417+
* Return: 0 on success, -errno otherwise.
385418
*/
386419
static int idpf_get_rxfh(struct net_device *netdev,
387420
struct ethtool_rxfh_param *rxfh)
388421
{
389422
struct idpf_netdev_priv *np = netdev_priv(netdev);
390423
struct idpf_rss_data *rss_data;
391424
struct idpf_adapter *adapter;
425+
struct idpf_vport *vport;
426+
bool rxhash_ena;
392427
int err = 0;
393428
u16 i;
394429

395430
idpf_vport_ctrl_lock(netdev);
431+
vport = idpf_netdev_to_vport(netdev);
396432

397433
adapter = np->adapter;
398434

@@ -402,17 +438,16 @@ static int idpf_get_rxfh(struct net_device *netdev,
402438
}
403439

404440
rss_data = &adapter->vport_config[np->vport_idx]->user_config.rss_data;
405-
if (!test_bit(IDPF_VPORT_UP, np->state))
406-
goto unlock_mutex;
407441

442+
rxhash_ena = idpf_is_feature_ena(vport, NETIF_F_RXHASH);
408443
rxfh->hfunc = ETH_RSS_HASH_TOP;
409444

410445
if (rxfh->key)
411446
memcpy(rxfh->key, rss_data->rss_key, rss_data->rss_key_size);
412447

413448
if (rxfh->indir) {
414449
for (i = 0; i < rss_data->rss_lut_size; i++)
415-
rxfh->indir[i] = rss_data->rss_lut[i];
450+
rxfh->indir[i] = rxhash_ena ? rss_data->rss_lut[i] : 0;
416451
}
417452

418453
unlock_mutex:
@@ -452,8 +487,6 @@ static int idpf_set_rxfh(struct net_device *netdev,
452487
}
453488

454489
rss_data = &adapter->vport_config[vport->idx]->user_config.rss_data;
455-
if (!test_bit(IDPF_VPORT_UP, np->state))
456-
goto unlock_mutex;
457490

458491
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
459492
rxfh->hfunc != ETH_RSS_HASH_TOP) {
@@ -469,7 +502,8 @@ static int idpf_set_rxfh(struct net_device *netdev,
469502
rss_data->rss_lut[lut] = rxfh->indir[lut];
470503
}
471504

472-
err = idpf_config_rss(vport);
505+
if (test_bit(IDPF_VPORT_UP, np->state))
506+
err = idpf_config_rss(vport);
473507

474508
unlock_mutex:
475509
idpf_vport_ctrl_unlock(netdev);

drivers/net/ethernet/intel/idpf/idpf_idc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ static void idpf_idc_vport_dev_down(struct idpf_adapter *adapter)
322322
for (i = 0; i < adapter->num_alloc_vports; i++) {
323323
struct idpf_vport *vport = adapter->vports[i];
324324

325-
if (!vport)
325+
if (!vport || !vport->vdev_info)
326326
continue;
327327

328328
idpf_unplug_aux_dev(vport->vdev_info->adev);

0 commit comments

Comments
 (0)