All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
	pabeni@redhat.com, horms@kernel.org, jiri@resnulli.us,
	toke@toke.dk, vinicius.gomes@intel.com,
	stephen@networkplumber.org, vladbu@nvidia.com,
	cake@lists.bufferbloat.net, bpf@vger.kernel.org,
	ghandatmanas@gmail.com, km.kim1503@gmail.com,
	security@kernel.org, Victor Nogueira <victor@mojatatu.com>
Subject: Re: [PATCH net] net/sched: Mark qdisc for deletion if graft cannot delete
Date: Tue, 10 Mar 2026 18:47:13 -0700	[thread overview]
Message-ID: <20260310184713.7e810431@kernel.org> (raw)
In-Reply-To: <20260307212058.169511-1-jhs@mojatatu.com>

On Sat,  7 Mar 2026 16:20:58 -0500 Jamal Hadi Salim wrote:
> Note: We tried a couple of different approaches that had smaller code
> footprint but were a bit fugly. The first approach was to use recursion
> on the qdisc hash table to iterate the descendants of the qdisc; however,
> the challenge here is if the graph depth is "high" - we may overflow the
> stack. The second approach was to use a breadth first search to achieve
> the same goal; the challenge here was it was a quadratic algorithm.

Lots of complexity when realistically only ingress/clsact support 
the unlocked operations. Can we not just take rtnl before the
references and not bother all the real qdiscs with this @#%$ ?
(diff just to illustrate the point not even compiled)

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 4829c27446e3..21b461f3323d 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -2255,6 +2255,7 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
 	int err;
 	int tp_created;
 	bool rtnl_held = false;
+	bool rtnl_take = false
 	u32 flags;
 
 replay:
@@ -2290,11 +2291,17 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
 		}
 	}
 
+	/* Realistically only INGRESS supports unlocked ops */
+	if (parent != TC_H_INGRESS) {
+		rtnl_held = true;
+		rtnl_lock();
+	}
+
 	/* Find head of filter chain. */
 
 	err = __tcf_qdisc_find(net, &q, &parent, t->tcm_ifindex, false, extack);
 	if (err)
-		return err;
+		goto errout;
 
 	if (tcf_proto_check_kind(tca[TCA_KIND], name)) {
 		NL_SET_ERR_MSG(extack, "Specified TC filter name too long");
@@ -2306,11 +2313,12 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
 	 * block is shared (no qdisc found), qdisc is not unlocked, classifier
 	 * type is not specified, classifier is not unlocked.
 	 */
-	if (rtnl_held ||
+	if (rtnl_take ||
 	    (q && !(q->ops->cl_ops->flags & QDISC_CLASS_OPS_DOIT_UNLOCKED)) ||
 	    !tcf_proto_is_unlocked(name)) {
+		if (!rtnl_held)
+			rtnl_lock();
 		rtnl_held = true;
-		rtnl_lock();
 	}
 
 	err = __tcf_qdisc_cl_find(q, parent, &cl, t->tcm_ifindex, extack);
@@ -2451,17 +2459,16 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
 	}
 	tcf_block_release(q, block, rtnl_held);
 
-	if (rtnl_held)
-		rtnl_unlock();
-
 	if (err == -EAGAIN) {
 		/* Take rtnl lock in case EAGAIN is caused by concurrent flush
 		 * of target chain.
 		 */
-		rtnl_held = true;
+		rtnl_take = true;
 		/* Replay the request. */
 		goto replay;
 	}
+	if (rtnl_held)
+		rtnl_unlock();
 	return err;
 
 errout_locked:

  reply	other threads:[~2026-03-11  1:47 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-07 21:20 [PATCH net] net/sched: Mark qdisc for deletion if graft cannot delete Jamal Hadi Salim
2026-03-11  1:47 ` Jakub Kicinski [this message]
2026-03-11 16:22   ` Jamal Hadi Salim
2026-03-12  0:52     ` Jakub Kicinski
2026-03-12 20:36       ` Jamal Hadi Salim
2026-03-12 23:51         ` Jakub Kicinski
2026-03-13 15:56           ` Jamal Hadi Salim
2026-03-13 19:36             ` Jamal Hadi Salim
2026-03-14 15:00               ` Jakub Kicinski
2026-03-15 15:56                 ` Jamal Hadi Salim
2026-03-27 13:58                   ` Jamal Hadi Salim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260310184713.7e810431@kernel.org \
    --to=kuba@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=cake@lists.bufferbloat.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=ghandatmanas@gmail.com \
    --cc=horms@kernel.org \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=km.kim1503@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=security@kernel.org \
    --cc=stephen@networkplumber.org \
    --cc=toke@toke.dk \
    --cc=victor@mojatatu.com \
    --cc=vinicius.gomes@intel.com \
    --cc=vladbu@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.