Skip to content

Commit e60fa8e

Browse files
author
Paolo Abeni
committed
Merge branch 'ethtool-rss-track-rss-ctx-busy-from-core'
Daniel Zahka says: ==================== ethtool: rss: track rss ctx busy from core This series prevents deletion of rss contexts that are in use by ntuple filters from ethtool core. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 5cb409b + 1ec4349 commit e60fa8e

File tree

4 files changed

+86
-2
lines changed

4 files changed

+86
-2
lines changed

net/ethtool/common.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,54 @@ int ethtool_check_max_channel(struct net_device *dev,
684684
return 0;
685685
}
686686

687+
int ethtool_check_rss_ctx_busy(struct net_device *dev, u32 rss_context)
688+
{
689+
const struct ethtool_ops *ops = dev->ethtool_ops;
690+
struct ethtool_rxnfc *info;
691+
int rc, i, rule_cnt;
692+
693+
if (!ops->get_rxnfc)
694+
return 0;
695+
696+
rule_cnt = ethtool_get_rxnfc_rule_count(dev);
697+
if (!rule_cnt)
698+
return 0;
699+
700+
if (rule_cnt < 0)
701+
return -EINVAL;
702+
703+
info = kvzalloc(struct_size(info, rule_locs, rule_cnt), GFP_KERNEL);
704+
if (!info)
705+
return -ENOMEM;
706+
707+
info->cmd = ETHTOOL_GRXCLSRLALL;
708+
info->rule_cnt = rule_cnt;
709+
rc = ops->get_rxnfc(dev, info, info->rule_locs);
710+
if (rc)
711+
goto out_free;
712+
713+
for (i = 0; i < rule_cnt; i++) {
714+
struct ethtool_rxnfc rule_info = {
715+
.cmd = ETHTOOL_GRXCLSRULE,
716+
.fs.location = info->rule_locs[i],
717+
};
718+
719+
rc = ops->get_rxnfc(dev, &rule_info, NULL);
720+
if (rc)
721+
goto out_free;
722+
723+
if (rule_info.fs.flow_type & FLOW_RSS &&
724+
rule_info.rss_context == rss_context) {
725+
rc = -EBUSY;
726+
goto out_free;
727+
}
728+
}
729+
730+
out_free:
731+
kvfree(info);
732+
return rc;
733+
}
734+
687735
int ethtool_check_ops(const struct ethtool_ops *ops)
688736
{
689737
if (WARN_ON(ops->set_coalesce && !ops->supported_coalesce_params))

net/ethtool/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ bool convert_legacy_settings_to_link_ksettings(
4747
int ethtool_check_max_channel(struct net_device *dev,
4848
struct ethtool_channels channels,
4949
struct genl_info *info);
50+
int ethtool_check_rss_ctx_busy(struct net_device *dev, u32 rss_context);
5051
int __ethtool_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info);
5152

5253
extern const struct ethtool_phy_ops *ethtool_phy_ops;

net/ethtool/ioctl.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,13 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
14621462
mutex_lock(&dev->ethtool->rss_lock);
14631463
locked = true;
14641464
}
1465+
1466+
if (rxfh.rss_context && rxfh_dev.rss_delete) {
1467+
ret = ethtool_check_rss_ctx_busy(dev, rxfh.rss_context);
1468+
if (ret)
1469+
goto out;
1470+
}
1471+
14651472
if (create) {
14661473
if (rxfh_dev.rss_delete) {
14671474
ret = -EINVAL;

tools/testing/selftests/drivers/net/hw/rss_ctx.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from lib.py import ksft_run, ksft_pr, ksft_exit, ksft_eq, ksft_ne, ksft_ge, ksft_lt
77
from lib.py import NetDrvEpEnv
88
from lib.py import EthtoolFamily, NetdevFamily
9-
from lib.py import KsftSkipEx
9+
from lib.py import KsftSkipEx, KsftFailEx
1010
from lib.py import rand_port
1111
from lib.py import ethtool, ip, defer, GenerateTraffic, CmdExitFailure
1212

@@ -606,6 +606,33 @@ def test_rss_context_overlap2(cfg):
606606
test_rss_context_overlap(cfg, True)
607607

608608

609+
def test_delete_rss_context_busy(cfg):
610+
"""
611+
Test that deletion returns -EBUSY when an rss context is being used
612+
by an ntuple filter.
613+
"""
614+
615+
require_ntuple(cfg)
616+
617+
# create additional rss context
618+
ctx_id = ethtool_create(cfg, "-X", "context new")
619+
ctx_deleter = defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete")
620+
621+
# utilize context from ntuple filter
622+
port = rand_port()
623+
flow = f"flow-type tcp{cfg.addr_ipver} dst-port {port} context {ctx_id}"
624+
ntuple_id = ethtool_create(cfg, "-N", flow)
625+
defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}")
626+
627+
# attempt to delete in-use context
628+
try:
629+
ctx_deleter.exec_only()
630+
ctx_deleter.cancel()
631+
raise KsftFailEx(f"deleted context {ctx_id} used by rule {ntuple_id}")
632+
except CmdExitFailure:
633+
pass
634+
635+
609636
def main() -> None:
610637
with NetDrvEpEnv(__file__, nsim_test=False) as cfg:
611638
cfg.ethnl = EthtoolFamily()
@@ -616,7 +643,8 @@ def main() -> None:
616643
test_rss_context, test_rss_context4, test_rss_context32,
617644
test_rss_context_dump, test_rss_context_queue_reconfigure,
618645
test_rss_context_overlap, test_rss_context_overlap2,
619-
test_rss_context_out_of_order, test_rss_context4_create_with_cfg],
646+
test_rss_context_out_of_order, test_rss_context4_create_with_cfg,
647+
test_delete_rss_context_busy],
620648
args=(cfg, ))
621649
ksft_exit()
622650

0 commit comments

Comments
 (0)