aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2008-11-26 00:13:31 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-26 00:13:31 -0500
commit71bcb09a57894fa35591ce93dd972065eeecb63a (patch)
tree50ca8a43125f0aa89f1444928a209420754a79f3 /net
parent0e991ec6a0340916d3f29bd5dcb35299069e7226 (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/sched/act_police.c25
-rw-r--r--net/sched/sch_api.c7
-rw-r--r--net/sched/sch_cbq.c33
-rw-r--r--net/sched/sch_drr.c26
-rw-r--r--net/sched/sch_hfsc.c25
-rw-r--r--net/sched/sch_htb.c22
6 files changed, 97 insertions, 41 deletions
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 38015b493947..e19a0261144a 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -185,14 +185,21 @@ override:
185 if (parm->peakrate.rate) { 185 if (parm->peakrate.rate) {
186 P_tab = qdisc_get_rtab(&parm->peakrate, 186 P_tab = qdisc_get_rtab(&parm->peakrate,
187 tb[TCA_POLICE_PEAKRATE]); 187 tb[TCA_POLICE_PEAKRATE]);
188 if (P_tab == NULL) { 188 if (P_tab == NULL)
189 qdisc_put_rtab(R_tab);
190 goto failure; 189 goto failure;
191 }
192 } 190 }
193 } 191 }
194 /* No failure allowed after this point */ 192
195 spin_lock_bh(&police->tcf_lock); 193 spin_lock_bh(&police->tcf_lock);
194 if (est) {
195 err = gen_replace_estimator(&police->tcf_bstats,
196 &police->tcf_rate_est,
197 &police->tcf_lock, est);
198 if (err)
199 goto failure_unlock;
200 }
201
202 /* No failure allowed after this point */
196 if (R_tab != NULL) { 203 if (R_tab != NULL) {
197 qdisc_put_rtab(police->tcfp_R_tab); 204 qdisc_put_rtab(police->tcfp_R_tab);
198 police->tcfp_R_tab = R_tab; 205 police->tcfp_R_tab = R_tab;
@@ -217,10 +224,6 @@ override:
217 224
218 if (tb[TCA_POLICE_AVRATE]) 225 if (tb[TCA_POLICE_AVRATE])
219 police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); 226 police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]);
220 if (est)
221 gen_replace_estimator(&police->tcf_bstats,
222 &police->tcf_rate_est,
223 &police->tcf_lock, est);
224 227
225 spin_unlock_bh(&police->tcf_lock); 228 spin_unlock_bh(&police->tcf_lock);
226 if (ret != ACT_P_CREATED) 229 if (ret != ACT_P_CREATED)
@@ -238,7 +241,13 @@ override:
238 a->priv = police; 241 a->priv = police;
239 return ret; 242 return ret;
240 243
244failure_unlock:
245 spin_unlock_bh(&police->tcf_lock);
241failure: 246failure:
247 if (P_tab)
248 qdisc_put_rtab(P_tab);
249 if (R_tab)
250 qdisc_put_rtab(R_tab);
242 if (ret == ACT_P_CREATED) 251 if (ret == ACT_P_CREATED)
243 kfree(police); 252 kfree(police);
244 return err; 253 return err;
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 3fcfd4ef11d1..f859dd5fabf4 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -880,9 +880,12 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
880 sch->stab = stab; 880 sch->stab = stab;
881 881
882 if (tca[TCA_RATE]) 882 if (tca[TCA_RATE])
883 /* NB: ignores errors from replace_estimator
884 because change can't be undone. */
883 gen_replace_estimator(&sch->bstats, &sch->rate_est, 885 gen_replace_estimator(&sch->bstats, &sch->rate_est,
884 qdisc_root_sleeping_lock(sch), 886 qdisc_root_sleeping_lock(sch),
885 tca[TCA_RATE]); 887 tca[TCA_RATE]);
888
886 return 0; 889 return 0;
887} 890}
888 891
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 3a9569a3396c..9e43ed949167 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1765,11 +1765,23 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1765 } 1765 }
1766 1766
1767 if (tb[TCA_CBQ_RATE]) { 1767 if (tb[TCA_CBQ_RATE]) {
1768 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]); 1768 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]),
1769 tb[TCA_CBQ_RTAB]);
1769 if (rtab == NULL) 1770 if (rtab == NULL)
1770 return -EINVAL; 1771 return -EINVAL;
1771 } 1772 }
1772 1773
1774 if (tca[TCA_RATE]) {
1775 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
1776 qdisc_root_sleeping_lock(sch),
1777 tca[TCA_RATE]);
1778 if (err) {
1779 if (rtab)
1780 qdisc_put_rtab(rtab);
1781 return err;
1782 }
1783 }
1784
1773 /* Change class parameters */ 1785 /* Change class parameters */
1774 sch_tree_lock(sch); 1786 sch_tree_lock(sch);
1775 1787
@@ -1805,10 +1817,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1805 1817
1806 sch_tree_unlock(sch); 1818 sch_tree_unlock(sch);
1807 1819
1808 if (tca[TCA_RATE])
1809 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1810 qdisc_root_sleeping_lock(sch),
1811 tca[TCA_RATE]);
1812 return 0; 1820 return 0;
1813 } 1821 }
1814 1822
@@ -1855,6 +1863,17 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1855 cl = kzalloc(sizeof(*cl), GFP_KERNEL); 1863 cl = kzalloc(sizeof(*cl), GFP_KERNEL);
1856 if (cl == NULL) 1864 if (cl == NULL)
1857 goto failure; 1865 goto failure;
1866
1867 if (tca[TCA_RATE]) {
1868 err = gen_new_estimator(&cl->bstats, &cl->rate_est,
1869 qdisc_root_sleeping_lock(sch),
1870 tca[TCA_RATE]);
1871 if (err) {
1872 kfree(cl);
1873 goto failure;
1874 }
1875 }
1876
1858 cl->R_tab = rtab; 1877 cl->R_tab = rtab;
1859 rtab = NULL; 1878 rtab = NULL;
1860 cl->refcnt = 1; 1879 cl->refcnt = 1;
@@ -1896,10 +1915,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1896 1915
1897 qdisc_class_hash_grow(sch, &q->clhash); 1916 qdisc_class_hash_grow(sch, &q->clhash);
1898 1917
1899 if (tca[TCA_RATE])
1900 gen_new_estimator(&cl->bstats, &cl->rate_est,
1901 qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
1902
1903 *arg = (unsigned long)cl; 1918 *arg = (unsigned long)cl;
1904 return 0; 1919 return 0;
1905 1920
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index e7a7e87b141a..f6b4fa97df70 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -82,15 +82,19 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
82 quantum = psched_mtu(qdisc_dev(sch)); 82 quantum = psched_mtu(qdisc_dev(sch));
83 83
84 if (cl != NULL) { 84 if (cl != NULL) {
85 if (tca[TCA_RATE]) {
86 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
87 qdisc_root_sleeping_lock(sch),
88 tca[TCA_RATE]);
89 if (err)
90 return err;
91 }
92
85 sch_tree_lock(sch); 93 sch_tree_lock(sch);
86 if (tb[TCA_DRR_QUANTUM]) 94 if (tb[TCA_DRR_QUANTUM])
87 cl->quantum = quantum; 95 cl->quantum = quantum;
88 sch_tree_unlock(sch); 96 sch_tree_unlock(sch);
89 97
90 if (tca[TCA_RATE])
91 gen_replace_estimator(&cl->bstats, &cl->rate_est,
92 qdisc_root_sleeping_lock(sch),
93 tca[TCA_RATE]);
94 return 0; 98 return 0;
95 } 99 }
96 100
@@ -106,10 +110,16 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
106 if (cl->qdisc == NULL) 110 if (cl->qdisc == NULL)
107 cl->qdisc = &noop_qdisc; 111 cl->qdisc = &noop_qdisc;
108 112
109 if (tca[TCA_RATE]) 113 if (tca[TCA_RATE]) {
110 gen_replace_estimator(&cl->bstats, &cl->rate_est, 114 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
111 qdisc_root_sleeping_lock(sch), 115 qdisc_root_sleeping_lock(sch),
112 tca[TCA_RATE]); 116 tca[TCA_RATE]);
117 if (err) {
118 qdisc_destroy(cl->qdisc);
119 kfree(cl);
120 return err;
121 }
122 }
113 123
114 sch_tree_lock(sch); 124 sch_tree_lock(sch);
115 qdisc_class_hash_insert(&q->clhash, &cl->common); 125 qdisc_class_hash_insert(&q->clhash, &cl->common);
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 613179c9969c..45c31b1a4e1d 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1018,6 +1018,14 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1018 } 1018 }
1019 cur_time = psched_get_time(); 1019 cur_time = psched_get_time();
1020 1020
1021 if (tca[TCA_RATE]) {
1022 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
1023 qdisc_root_sleeping_lock(sch),
1024 tca[TCA_RATE]);
1025 if (err)
1026 return err;
1027 }
1028
1021 sch_tree_lock(sch); 1029 sch_tree_lock(sch);
1022 if (rsc != NULL) 1030 if (rsc != NULL)
1023 hfsc_change_rsc(cl, rsc, cur_time); 1031 hfsc_change_rsc(cl, rsc, cur_time);
@@ -1034,10 +1042,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1034 } 1042 }
1035 sch_tree_unlock(sch); 1043 sch_tree_unlock(sch);
1036 1044
1037 if (tca[TCA_RATE])
1038 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1039 qdisc_root_sleeping_lock(sch),
1040 tca[TCA_RATE]);
1041 return 0; 1045 return 0;
1042 } 1046 }
1043 1047
@@ -1063,6 +1067,16 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1063 if (cl == NULL) 1067 if (cl == NULL)
1064 return -ENOBUFS; 1068 return -ENOBUFS;
1065 1069
1070 if (tca[TCA_RATE]) {
1071 err = gen_new_estimator(&cl->bstats, &cl->rate_est,
1072 qdisc_root_sleeping_lock(sch),
1073 tca[TCA_RATE]);
1074 if (err) {
1075 kfree(cl);
1076 return err;
1077 }
1078 }
1079
1066 if (rsc != NULL) 1080 if (rsc != NULL)
1067 hfsc_change_rsc(cl, rsc, 0); 1081 hfsc_change_rsc(cl, rsc, 0);
1068 if (fsc != NULL) 1082 if (fsc != NULL)
@@ -1093,9 +1107,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1093 1107
1094 qdisc_class_hash_grow(sch, &q->clhash); 1108 qdisc_class_hash_grow(sch, &q->clhash);
1095 1109
1096 if (tca[TCA_RATE])
1097 gen_new_estimator(&cl->bstats, &cl->rate_est,
1098 qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
1099 *arg = (unsigned long)cl; 1110 *arg = (unsigned long)cl;
1100 return 0; 1111 return 0;
1101} 1112}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 3a119f576bb3..8a4519989732 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1332,9 +1332,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1332 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL) 1332 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
1333 goto failure; 1333 goto failure;
1334 1334
1335 gen_new_estimator(&cl->bstats, &cl->rate_est, 1335 err = gen_new_estimator(&cl->bstats, &cl->rate_est,
1336 qdisc_root_sleeping_lock(sch), 1336 qdisc_root_sleeping_lock(sch),
1337 tca[TCA_RATE] ? : &est.nla); 1337 tca[TCA_RATE] ? : &est.nla);
1338 if (err) {
1339 kfree(cl);
1340 goto failure;
1341 }
1342
1338 cl->refcnt = 1; 1343 cl->refcnt = 1;
1339 cl->children = 0; 1344 cl->children = 0;
1340 INIT_LIST_HEAD(&cl->un.leaf.drop_list); 1345 INIT_LIST_HEAD(&cl->un.leaf.drop_list);
@@ -1386,10 +1391,13 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1386 if (parent) 1391 if (parent)
1387 parent->children++; 1392 parent->children++;
1388 } else { 1393 } else {
1389 if (tca[TCA_RATE]) 1394 if (tca[TCA_RATE]) {
1390 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1395 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
1391 qdisc_root_sleeping_lock(sch), 1396 qdisc_root_sleeping_lock(sch),
1392 tca[TCA_RATE]); 1397 tca[TCA_RATE]);
1398 if (err)
1399 return err;
1400 }
1393 sch_tree_lock(sch); 1401 sch_tree_lock(sch);
1394 } 1402 }
1395 1403