--- x/net/sched/sch_taprio.c +++ y/net/sched/sch_taprio.c @@ -1975,9 +1975,12 @@ static int taprio_change(struct Qdisc *s goto unlock; } + spin_lock_irqsave(&q->current_entry_lock, flags); + admin = rtnl_dereference(q->admin_sched); rcu_assign_pointer(q->admin_sched, new_admin); if (admin) call_rcu(&admin->rcu, taprio_free_sched_cb); + spin_unlock_irqrestore(&q->current_entry_lock, flags); } else { setup_first_end_time(q, new_admin, start); @@ -2393,6 +2396,7 @@ static int taprio_dump(struct Qdisc *sch struct sched_gate_list *oper, *admin; struct tc_mqprio_qopt opt = { 0 }; struct nlattr *nest, *sched_nest; + int active = hrtimer_cancel(&q->advance_timer); oper = rtnl_dereference(q->oper_sched); admin = rtnl_dereference(q->admin_sched); @@ -2436,6 +2440,10 @@ static int taprio_dump(struct Qdisc *sch nla_nest_end(skb, sched_nest); done: + if (active) + hrtimer_start(&q->advance_timer, + hrtimer_get_expires(&q->advance_timer), + HRTIMER_MODE_ABS); return nla_nest_end(skb, nest); admin_error: @@ -2445,6 +2453,10 @@ options_error: nla_nest_cancel(skb, nest); start_error: + if (active) + hrtimer_start(&q->advance_timer, + hrtimer_get_expires(&q->advance_timer), + HRTIMER_MODE_ABS); return -ENOSPC; }