diff mbox series

[net-next,RFC,V3,1/2] net: sched: generalize check for no-op qdisc on TX queue

Message ID 174464555063.20396.9545196538212416415.stgit@firesoul (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series veth: qdisc backpressure and qdisc check refactor | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 14 this patch: 14
netdev/build_tools success Errors and warnings before: 26 (+2) this patch: 26 (+2)
netdev/cc_maintainers warning 3 maintainers not CCed: andrew+netdev@lunn.ch edumazet@google.com horms@kernel.org
netdev/build_clang success Errors and warnings before: 18 this patch: 18
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1414 this patch: 1414
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 35 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jesper Dangaard Brouer April 14, 2025, 3:45 p.m. UTC
WARNING: Testing show this is NOT correct!
 - I need help figuring out why this patch is incorrect.
 - Testing against &noop_qdisc is not the same as q->enqueue == NULL
 - I copied test (txq->qdisc == &noop_qdisc) from qdisc_tx_is_noop
 - Q: is qdisc_tx_is_noop() function incorrect?

The vrf driver includes an open-coded check to determine whether a TX
queue (netdev_queue) has a real qdisc attached. This is done by testing
whether qdisc->enqueue is NULL, which is functionally equivalent to
checking whether the qdisc is &noop_qdisc.

This equivalence stems from noqueue_init(), which explicitly clears the
enqueue pointer to signal no-op behavior to __dev_queue_xmit().

This patch introduces a shared helper, qdisc_txq_is_noop(), to clarify
intent and make this logic reusable. The vrf driver is updated to use
this new helper.

Subsequent patches will make further use of this helper in other drivers,
such as veth.

This is a non-functional change.

Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
---
 drivers/net/vrf.c         |    4 +---
 include/net/sch_generic.h |    7 ++++++-
 2 files changed, 7 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 7168b33adadb..f0a24fc85945 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -343,15 +343,13 @@  static int vrf_ifindex_lookup_by_table_id(struct net *net, u32 table_id)
 static bool qdisc_tx_is_default(const struct net_device *dev)
 {
 	struct netdev_queue *txq;
-	struct Qdisc *qdisc;
 
 	if (dev->num_tx_queues > 1)
 		return false;
 
 	txq = netdev_get_tx_queue(dev, 0);
-	qdisc = rcu_access_pointer(txq->qdisc);
 
-	return !qdisc->enqueue;
+	return qdisc_txq_is_noop(txq);
 }
 
 /* Local traffic destined to local address. Reinsert the packet to rx
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index d48c657191cd..a1f5560350a6 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -803,6 +803,11 @@  static inline bool qdisc_tx_changing(const struct net_device *dev)
 	return false;
 }
 
+static inline bool qdisc_txq_is_noop(const struct netdev_queue *txq)
+{
+	return rcu_access_pointer(txq->qdisc) == &noop_qdisc;
+}
+
 /* Is the device using the noop qdisc on all queues?  */
 static inline bool qdisc_tx_is_noop(const struct net_device *dev)
 {
@@ -810,7 +815,7 @@  static inline bool qdisc_tx_is_noop(const struct net_device *dev)
 
 	for (i = 0; i < dev->num_tx_queues; i++) {
 		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
-		if (rcu_access_pointer(txq->qdisc) != &noop_qdisc)
+		if (!qdisc_txq_is_noop(txq))
 			return false;
 	}
 	return true;