Skip to content

Commit 64445dd

Browse files
Sebastian Andrzej Siewiordavem330
authored andcommitted
net: dev: Always serialize on Qdisc::busylock in __dev_xmit_skb() on PREEMPT_RT.
The root-lock is dropped before dev_hard_start_xmit() is invoked and after setting the __QDISC___STATE_RUNNING bit. If the Qdisc owner is preempted by another sender/task with a higher priority then this new sender won't be able to submit packets to the NIC directly instead they will be enqueued into the Qdisc. The NIC will remain idle until the Qdisc owner is scheduled again and finishes the job. By serializing every task on the ->busylock then the task will be preempted by a sender only after the Qdisc has no owner. Always serialize on the busylock on PREEMPT_RT. Signed-off-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 93d576f commit 64445dd

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

net/core/dev.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3719,8 +3719,12 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
37193719
* separate lock before trying to get qdisc main lock.
37203720
* This permits qdisc->running owner to get the lock more
37213721
* often and dequeue packets faster.
3722+
* On PREEMPT_RT it is possible to preempt the qdisc owner during xmit
3723+
* and then other tasks will only enqueue packets. The packets will be
3724+
* sent after the qdisc owner is scheduled again. To prevent this
3725+
* scenario the task always serialize on the lock.
37223726
*/
3723-
contended = qdisc_is_running(q);
3727+
contended = IS_ENABLED(CONFIG_PREEMPT_RT) || qdisc_is_running(q);
37243728
if (unlikely(contended))
37253729
spin_lock(&q->busylock);
37263730

0 commit comments

Comments
 (0)