Skip to content

Commit dc97553

Browse files
kuba-moodavem330
authored andcommitted
ethtool: fix the state of additional contexts with old API
We expect drivers implementing the new create/modify/destroy API to populate the defaults in struct ethtool_rxfh_context. In legacy API ctx isn't even passed, and rxfh.indir / rxfh.key are NULL so drivers can't give us defaults even if they want to. Call get_rxfh() to fetch the values. We can reuse rxfh_dev for the get_rxfh(), rxfh stores the input from the user. This fixes IOCTL reporting 0s instead of the default key / indir table for drivers using legacy API. Add a check to try to catch drivers using the new API but not populating the key. Fixes: 7964e78 ("net: ethtool: use the tracking array for get_rxfh on custom RSS contexts") Signed-off-by: Jakub Kicinski <[email protected]> Reviewed-by: Edward Cree <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7195f0e commit dc97553

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

net/ethtool/ioctl.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,10 +1382,9 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
13821382
rxfh.input_xfrm == RXH_XFRM_NO_CHANGE))
13831383
return -EINVAL;
13841384

1385-
if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
1386-
indir_bytes = dev_indir_size * sizeof(rxfh_dev.indir[0]);
1385+
indir_bytes = dev_indir_size * sizeof(rxfh_dev.indir[0]);
13871386

1388-
rss_config = kzalloc(indir_bytes + rxfh.key_size, GFP_USER);
1387+
rss_config = kzalloc(indir_bytes + dev_key_size, GFP_USER);
13891388
if (!rss_config)
13901389
return -ENOMEM;
13911390

@@ -1475,16 +1474,21 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
14751474
rxfh_dev.input_xfrm = rxfh.input_xfrm;
14761475

14771476
if (rxfh.rss_context && ops->create_rxfh_context) {
1478-
if (create)
1477+
if (create) {
14791478
ret = ops->create_rxfh_context(dev, ctx, &rxfh_dev,
14801479
extack);
1481-
else if (rxfh_dev.rss_delete)
1480+
/* Make sure driver populates defaults */
1481+
WARN_ON_ONCE(!ret && !rxfh_dev.key &&
1482+
!memchr_inv(ethtool_rxfh_context_key(ctx),
1483+
0, ctx->key_size));
1484+
} else if (rxfh_dev.rss_delete) {
14821485
ret = ops->remove_rxfh_context(dev, ctx,
14831486
rxfh.rss_context,
14841487
extack);
1485-
else
1488+
} else {
14861489
ret = ops->modify_rxfh_context(dev, ctx, &rxfh_dev,
14871490
extack);
1491+
}
14881492
} else {
14891493
ret = ops->set_rxfh(dev, &rxfh_dev, extack);
14901494
}
@@ -1523,6 +1527,22 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
15231527
kfree(ctx);
15241528
goto out;
15251529
}
1530+
1531+
/* Fetch the defaults for the old API, in the new API drivers
1532+
* should write defaults into ctx themselves.
1533+
*/
1534+
rxfh_dev.indir = (u32 *)rss_config;
1535+
rxfh_dev.indir_size = dev_indir_size;
1536+
1537+
rxfh_dev.key = rss_config + indir_bytes;
1538+
rxfh_dev.key_size = dev_key_size;
1539+
1540+
ret = ops->get_rxfh(dev, &rxfh_dev);
1541+
if (WARN_ON(ret)) {
1542+
xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context);
1543+
kfree(ctx);
1544+
goto out;
1545+
}
15261546
}
15271547
if (rxfh_dev.rss_delete) {
15281548
WARN_ON(xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context) != ctx);
@@ -1531,12 +1551,14 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
15311551
if (rxfh_dev.indir) {
15321552
for (i = 0; i < dev_indir_size; i++)
15331553
ethtool_rxfh_context_indir(ctx)[i] = rxfh_dev.indir[i];
1534-
ctx->indir_configured = 1;
1554+
ctx->indir_configured =
1555+
rxfh.indir_size &&
1556+
rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE;
15351557
}
15361558
if (rxfh_dev.key) {
15371559
memcpy(ethtool_rxfh_context_key(ctx), rxfh_dev.key,
15381560
dev_key_size);
1539-
ctx->key_configured = 1;
1561+
ctx->key_configured = !!rxfh.key_size;
15401562
}
15411563
if (rxfh_dev.hfunc != ETH_RSS_HASH_NO_CHANGE)
15421564
ctx->hfunc = rxfh_dev.hfunc;

0 commit comments

Comments
 (0)