aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/cls_api.c
diff options
context:
space:
mode:
authorJiri Pirko <[email protected]>2024-01-04 12:58:44 +0000
committerDavid S. Miller <[email protected]>2024-01-05 11:19:08 +0000
commit94e2557d086ad831027c54bc9c2130d337c72814 (patch)
tree3fa3e317ccf6f36338e361194980de127b618cd3 /net/sched/cls_api.c
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net (diff)
downloadkernel-94e2557d086ad831027c54bc9c2130d337c72814.tar.gz
kernel-94e2557d086ad831027c54bc9c2130d337c72814.zip
net: sched: move block device tracking into tcf_block_get/put_ext()
Inserting the device to block xarray in qdisc_create() is not suitable place to do this. As it requires use of tcf_block() callback, it causes multiple issues. It is called for all qdisc types, which is incorrect. So, instead, move it to more suitable place, which is tcf_block_get_ext() and make sure it is only done for qdiscs that use block infrastructure and also only for blocks which are shared. Symmetrically, alter the cleanup path, move the xarray entry removal into tcf_block_put_ext(). Fixes: 913b47d3424e ("net/sched: Introduce tc block netdev tracking infra") Reported-by: Ido Schimmel <[email protected]> Closes: https://lore.kernel.org/all/ZY1hBb8GFwycfgvd@shredder/ Reported-by: Kui-Feng Lee <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Reported-and-tested-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/ Reported-and-tested-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/ Reported-and-tested-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Jiri Pirko <[email protected]> Tested-by: Ido Schimmel <[email protected]> Reviewed-by: Victor Nogueira <[email protected]> Tested-by: Victor Nogueira <[email protected]> Reviewed-by: Jamal Hadi Salim <[email protected]> Acked-by: Jamal Hadi Salim <[email protected]> Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r--net/sched/cls_api.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index adf5de1ff773..253b26f2eddd 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1428,6 +1428,7 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
struct tcf_block_ext_info *ei,
struct netlink_ext_ack *extack)
{
+ struct net_device *dev = qdisc_dev(q);
struct net *net = qdisc_net(q);
struct tcf_block *block = NULL;
int err;
@@ -1461,9 +1462,18 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
if (err)
goto err_block_offload_bind;
+ if (tcf_block_shared(block)) {
+ err = xa_insert(&block->ports, dev->ifindex, dev, GFP_KERNEL);
+ if (err) {
+ NL_SET_ERR_MSG(extack, "block dev insert failed");
+ goto err_dev_insert;
+ }
+ }
+
*p_block = block;
return 0;
+err_dev_insert:
err_block_offload_bind:
tcf_chain0_head_change_cb_del(block, ei);
err_chain0_head_change_cb_add:
@@ -1502,8 +1512,12 @@ EXPORT_SYMBOL(tcf_block_get);
void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
struct tcf_block_ext_info *ei)
{
+ struct net_device *dev = qdisc_dev(q);
+
if (!block)
return;
+ if (tcf_block_shared(block))
+ xa_erase(&block->ports, dev->ifindex);
tcf_chain0_head_change_cb_del(block, ei);
tcf_block_owner_del(block, q, ei->binder_type);