diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 1ee396ce0eda8..e8034756cbf8e 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1334,4 +1334,11 @@ static inline void skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) qstats_overlimit_inc(res->qstats); } +/* Make sure qdisc is no longer in SCHED state. */ +static inline void qdisc_synchronize(const struct Qdisc *q) +{ + while (test_bit(__QDISC_STATE_SCHED, &q->state)) + msleep(1); +} + #endif diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 506ebae1f72cf..4278a466cb50d 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1622,6 +1622,8 @@ static void taprio_reset(struct Qdisc *sch) int i; hrtimer_cancel(&q->advance_timer); + qdisc_synchronize(sch); + if (q->qdiscs) { for (i = 0; i < dev->num_tx_queues && q->qdiscs[i]; i++) qdisc_reset(q->qdiscs[i]); @@ -1644,6 +1646,7 @@ static void taprio_destroy(struct Qdisc *sch) * happens in qdisc_create(), after taprio_init() has been called. */ hrtimer_cancel(&q->advance_timer); + qdisc_synchronize(sch); taprio_disable_offload(dev, q, NULL);