forked from luck/tmp_suning_uos_patched
tc: check for errors in gen_rate_estimator creation
The functions gen_new_estimator and gen_replace_estimator can return errors, but they were being ignored. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0e991ec6a0
commit
71bcb09a57
|
@ -185,14 +185,21 @@ static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est,
|
|||
if (parm->peakrate.rate) {
|
||||
P_tab = qdisc_get_rtab(&parm->peakrate,
|
||||
tb[TCA_POLICE_PEAKRATE]);
|
||||
if (P_tab == NULL) {
|
||||
qdisc_put_rtab(R_tab);
|
||||
if (P_tab == NULL)
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* No failure allowed after this point */
|
||||
|
||||
spin_lock_bh(&police->tcf_lock);
|
||||
if (est) {
|
||||
err = gen_replace_estimator(&police->tcf_bstats,
|
||||
&police->tcf_rate_est,
|
||||
&police->tcf_lock, est);
|
||||
if (err)
|
||||
goto failure_unlock;
|
||||
}
|
||||
|
||||
/* No failure allowed after this point */
|
||||
if (R_tab != NULL) {
|
||||
qdisc_put_rtab(police->tcfp_R_tab);
|
||||
police->tcfp_R_tab = R_tab;
|
||||
|
@ -217,10 +224,6 @@ static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est,
|
|||
|
||||
if (tb[TCA_POLICE_AVRATE])
|
||||
police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]);
|
||||
if (est)
|
||||
gen_replace_estimator(&police->tcf_bstats,
|
||||
&police->tcf_rate_est,
|
||||
&police->tcf_lock, est);
|
||||
|
||||
spin_unlock_bh(&police->tcf_lock);
|
||||
if (ret != ACT_P_CREATED)
|
||||
|
@ -238,7 +241,13 @@ static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est,
|
|||
a->priv = police;
|
||||
return ret;
|
||||
|
||||
failure_unlock:
|
||||
spin_unlock_bh(&police->tcf_lock);
|
||||
failure:
|
||||
if (P_tab)
|
||||
qdisc_put_rtab(P_tab);
|
||||
if (R_tab)
|
||||
qdisc_put_rtab(R_tab);
|
||||
if (ret == ACT_P_CREATED)
|
||||
kfree(police);
|
||||
return err;
|
||||
|
|
|
@ -880,9 +880,12 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
|
|||
sch->stab = stab;
|
||||
|
||||
if (tca[TCA_RATE])
|
||||
/* NB: ignores errors from replace_estimator
|
||||
because change can't be undone. */
|
||||
gen_replace_estimator(&sch->bstats, &sch->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1765,11 +1765,23 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
|
|||
}
|
||||
|
||||
if (tb[TCA_CBQ_RATE]) {
|
||||
rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
|
||||
rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]),
|
||||
tb[TCA_CBQ_RTAB]);
|
||||
if (rtab == NULL)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tca[TCA_RATE]) {
|
||||
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (err) {
|
||||
if (rtab)
|
||||
qdisc_put_rtab(rtab);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change class parameters */
|
||||
sch_tree_lock(sch);
|
||||
|
||||
|
@ -1805,10 +1817,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
|
|||
|
||||
sch_tree_unlock(sch);
|
||||
|
||||
if (tca[TCA_RATE])
|
||||
gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1855,6 +1863,17 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
|
|||
cl = kzalloc(sizeof(*cl), GFP_KERNEL);
|
||||
if (cl == NULL)
|
||||
goto failure;
|
||||
|
||||
if (tca[TCA_RATE]) {
|
||||
err = gen_new_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (err) {
|
||||
kfree(cl);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
cl->R_tab = rtab;
|
||||
rtab = NULL;
|
||||
cl->refcnt = 1;
|
||||
|
@ -1896,10 +1915,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
|
|||
|
||||
qdisc_class_hash_grow(sch, &q->clhash);
|
||||
|
||||
if (tca[TCA_RATE])
|
||||
gen_new_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
|
||||
|
||||
*arg = (unsigned long)cl;
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -82,15 +82,19 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
quantum = psched_mtu(qdisc_dev(sch));
|
||||
|
||||
if (cl != NULL) {
|
||||
if (tca[TCA_RATE]) {
|
||||
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
sch_tree_lock(sch);
|
||||
if (tb[TCA_DRR_QUANTUM])
|
||||
cl->quantum = quantum;
|
||||
sch_tree_unlock(sch);
|
||||
|
||||
if (tca[TCA_RATE])
|
||||
gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,10 +110,16 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
if (cl->qdisc == NULL)
|
||||
cl->qdisc = &noop_qdisc;
|
||||
|
||||
if (tca[TCA_RATE])
|
||||
gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (tca[TCA_RATE]) {
|
||||
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (err) {
|
||||
qdisc_destroy(cl->qdisc);
|
||||
kfree(cl);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
sch_tree_lock(sch);
|
||||
qdisc_class_hash_insert(&q->clhash, &cl->common);
|
||||
|
|
|
@ -1018,6 +1018,14 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
}
|
||||
cur_time = psched_get_time();
|
||||
|
||||
if (tca[TCA_RATE]) {
|
||||
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
sch_tree_lock(sch);
|
||||
if (rsc != NULL)
|
||||
hfsc_change_rsc(cl, rsc, cur_time);
|
||||
|
@ -1034,10 +1042,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
}
|
||||
sch_tree_unlock(sch);
|
||||
|
||||
if (tca[TCA_RATE])
|
||||
gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1063,6 +1067,16 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
if (cl == NULL)
|
||||
return -ENOBUFS;
|
||||
|
||||
if (tca[TCA_RATE]) {
|
||||
err = gen_new_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (err) {
|
||||
kfree(cl);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (rsc != NULL)
|
||||
hfsc_change_rsc(cl, rsc, 0);
|
||||
if (fsc != NULL)
|
||||
|
@ -1093,9 +1107,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
|||
|
||||
qdisc_class_hash_grow(sch, &q->clhash);
|
||||
|
||||
if (tca[TCA_RATE])
|
||||
gen_new_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
|
||||
*arg = (unsigned long)cl;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1332,9 +1332,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
|||
if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
|
||||
goto failure;
|
||||
|
||||
gen_new_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE] ? : &est.nla);
|
||||
err = gen_new_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE] ? : &est.nla);
|
||||
if (err) {
|
||||
kfree(cl);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
cl->refcnt = 1;
|
||||
cl->children = 0;
|
||||
INIT_LIST_HEAD(&cl->un.leaf.drop_list);
|
||||
|
@ -1386,10 +1391,13 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
|||
if (parent)
|
||||
parent->children++;
|
||||
} else {
|
||||
if (tca[TCA_RATE])
|
||||
gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (tca[TCA_RATE]) {
|
||||
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
|
||||
qdisc_root_sleeping_lock(sch),
|
||||
tca[TCA_RATE]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
sch_tree_lock(sch);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user