Skip to content

Commit ca1e4ab

Browse files
Maxim Mikityanskiykuba-moo
authored andcommitted
net: sched: Add multi-queue support to sch_tree_lock
The existing qdiscs that set TCQ_F_MQROOT don't use sch_tree_lock. However, hardware-offloaded HTB will start setting this flag while also using sch_tree_lock. The current implementation of sch_tree_lock basically locks on qdisc->dev_queue->qdisc, and it works fine when the tree is attached to some queue. However, it's not the case for MQROOT qdiscs: such a qdisc is the root itself, and its dev_queue just points to queue 0, while not actually being used, because there are real per-queue qdiscs. This patch changes the logic of sch_tree_lock and sch_tree_unlock to lock the qdisc itself if it's the MQROOT. Signed-off-by: Maxim Mikityanskiy <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 04a8863 commit ca1e4ab

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

include/net/sch_generic.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,14 +552,20 @@ static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc)
552552
return qdisc->dev_queue->dev;
553553
}
554554

555-
static inline void sch_tree_lock(const struct Qdisc *q)
555+
static inline void sch_tree_lock(struct Qdisc *q)
556556
{
557-
spin_lock_bh(qdisc_root_sleeping_lock(q));
557+
if (q->flags & TCQ_F_MQROOT)
558+
spin_lock_bh(qdisc_lock(q));
559+
else
560+
spin_lock_bh(qdisc_root_sleeping_lock(q));
558561
}
559562

560-
static inline void sch_tree_unlock(const struct Qdisc *q)
563+
static inline void sch_tree_unlock(struct Qdisc *q)
561564
{
562-
spin_unlock_bh(qdisc_root_sleeping_lock(q));
565+
if (q->flags & TCQ_F_MQROOT)
566+
spin_unlock_bh(qdisc_lock(q));
567+
else
568+
spin_unlock_bh(qdisc_root_sleeping_lock(q));
563569
}
564570

565571
extern struct Qdisc noop_qdisc;

0 commit comments

Comments
 (0)