diff options
author | Vladimir Oltean <vladimir.oltean@nxp.com> | 2022-09-15 13:50:42 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-09-20 13:53:33 -0700 |
commit | 9af23657b33679b5b8d8579ca1cc0214398f576f (patch) | |
tree | 9a1a9b70aaf2d8081a8c4e12c0e33452fd955b75 | |
parent | 18cdd2f0998a4967b1fff4c43ed9aef049e42c39 (diff) |
net/sched: taprio: use rtnl_dereference for oper and admin sched in taprio_destroy()
Sparse complains that taprio_destroy() dereferences q->oper_sched and
q->admin_sched without rcu_dereference(), since they are marked as __rcu
in the taprio private structure.
1671:28: warning: incorrect type in argument 1 (different address spaces)
1671:28: expected struct callback_head *head
1671:28: got struct callback_head [noderef] __rcu *
1674:28: warning: incorrect type in argument 1 (different address spaces)
1674:28: expected struct callback_head *head
1674:28: got struct callback_head [noderef] __rcu *
To silence that build warning, do actually use rtnl_dereference(), since
we know the rtnl_mutex is held at the time of q->destroy().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | net/sched/sch_taprio.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 017ccf5431aa..38d742b335d0 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1634,6 +1634,7 @@ static void taprio_destroy(struct Qdisc *sch) { struct taprio_sched *q = qdisc_priv(sch); struct net_device *dev = qdisc_dev(sch); + struct sched_gate_list *oper, *admin; unsigned int i; spin_lock(&taprio_list_lock); @@ -1657,11 +1658,14 @@ static void taprio_destroy(struct Qdisc *sch) netdev_reset_tc(dev); - if (q->oper_sched) - call_rcu(&q->oper_sched->rcu, taprio_free_sched_cb); + oper = rtnl_dereference(q->oper_sched); + admin = rtnl_dereference(q->admin_sched); + + if (oper) + call_rcu(&oper->rcu, taprio_free_sched_cb); - if (q->admin_sched) - call_rcu(&q->admin_sched->rcu, taprio_free_sched_cb); + if (admin) + call_rcu(&admin->rcu, taprio_free_sched_cb); } static int taprio_init(struct Qdisc *sch, struct nlattr *opt, |