diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 4195a4bc26ca..9e418f94757d 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -337,13 +337,16 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, #endif if (likely(skb)) { - HARD_TX_LOCK(dev, txq, smp_processor_id()); - if (!netif_xmit_frozen_or_stopped(txq)) - skb = dev_hard_start_xmit(skb, dev, txq, &ret); - else - qdisc_maybe_clear_missed(q, txq); + int cpu = smp_processor_id(); + if (READ_ONCE(txq->xmit_lock_owner) != cpu) { + HARD_TX_LOCK(dev, txq, cpu); + if (!netif_xmit_frozen_or_stopped(txq)) + skb = dev_hard_start_xmit(skb, dev, txq, &ret); + else + qdisc_maybe_clear_missed(q, txq); - HARD_TX_UNLOCK(dev, txq); + HARD_TX_UNLOCK(dev, txq); + } } else { if (root_lock) spin_lock(root_lock);