net_sched: move tcf_lock down after gen_replace_estimator()
Laura reported a sleep-in-atomic kernel warning inside tcf_act_police_init() which calls gen_replace_estimator() with spinlock protection. It is not necessary in this case, we already have RTNL lock here so it is enough to protect concurrent writers. For the reader, i.e. tcf_act_police(), it needs to make decision based on this rate estimator, in the worst case we drop more/less packets than necessary while changing the rate in parallel, it is still acceptable. Reported-by: Laura Abbott <labbott@redhat.com> Reported-by: Nick Huber <nicholashuber@gmail.com> Cc: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
20a3d5bf5e
commit
74030603df
|
@ -132,21 +132,21 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_bh(&police->tcf_lock);
|
|
||||||
if (est) {
|
if (est) {
|
||||||
err = gen_replace_estimator(&police->tcf_bstats, NULL,
|
err = gen_replace_estimator(&police->tcf_bstats, NULL,
|
||||||
&police->tcf_rate_est,
|
&police->tcf_rate_est,
|
||||||
&police->tcf_lock,
|
&police->tcf_lock,
|
||||||
NULL, est);
|
NULL, est);
|
||||||
if (err)
|
if (err)
|
||||||
goto failure_unlock;
|
goto failure;
|
||||||
} else if (tb[TCA_POLICE_AVRATE] &&
|
} else if (tb[TCA_POLICE_AVRATE] &&
|
||||||
(ret == ACT_P_CREATED ||
|
(ret == ACT_P_CREATED ||
|
||||||
!gen_estimator_active(&police->tcf_rate_est))) {
|
!gen_estimator_active(&police->tcf_rate_est))) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto failure_unlock;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_bh(&police->tcf_lock);
|
||||||
/* No failure allowed after this point */
|
/* No failure allowed after this point */
|
||||||
police->tcfp_mtu = parm->mtu;
|
police->tcfp_mtu = parm->mtu;
|
||||||
if (police->tcfp_mtu == 0) {
|
if (police->tcfp_mtu == 0) {
|
||||||
|
@ -192,8 +192,6 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
failure_unlock:
|
|
||||||
spin_unlock_bh(&police->tcf_lock);
|
|
||||||
failure:
|
failure:
|
||||||
qdisc_put_rtab(P_tab);
|
qdisc_put_rtab(P_tab);
|
||||||
qdisc_put_rtab(R_tab);
|
qdisc_put_rtab(R_tab);
|
||||||
|
|
Loading…
Reference in New Issue