aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sched/sch_atm.c3
-rw-r--r--net/sched/sch_cbq.c7
-rw-r--r--net/sched/sch_drr.c3
-rw-r--r--net/sched/sch_dsmark.c3
-rw-r--r--net/sched/sch_hfsc.c3
-rw-r--r--net/sched/sch_htb.c4
-rw-r--r--net/sched/sch_multiq.c16
-rw-r--r--net/sched/sch_netem.c5
-rw-r--r--net/sched/sch_prio.c16
-rw-r--r--net/sched/sch_red.c6
-rw-r--r--net/sched/sch_tbf.c17
11 files changed, 52 insertions, 31 deletions
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index ca90f6e59aee..2a8b83af7c47 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -102,7 +102,8 @@ static int atm_tc_graft(struct Qdisc *sch, unsigned long arg,
102 return -EINVAL; 102 return -EINVAL;
103 if (!new) 103 if (!new)
104 new = &noop_qdisc; 104 new = &noop_qdisc;
105 *old = xchg(&flow->q, new); 105 *old = flow->q;
106 flow->q = new;
106 if (*old) 107 if (*old)
107 qdisc_reset(*old); 108 qdisc_reset(*old);
108 return 0; 109 return 0;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index a99e37e9e6f1..3a9569a3396c 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1635,7 +1635,8 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1635#endif 1635#endif
1636 } 1636 }
1637 sch_tree_lock(sch); 1637 sch_tree_lock(sch);
1638 *old = xchg(&cl->q, new); 1638 *old = cl->q;
1639 cl->q = new;
1639 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); 1640 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1640 qdisc_reset(*old); 1641 qdisc_reset(*old);
1641 sch_tree_unlock(sch); 1642 sch_tree_unlock(sch);
@@ -1776,8 +1777,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1776 cbq_deactivate_class(cl); 1777 cbq_deactivate_class(cl);
1777 1778
1778 if (rtab) { 1779 if (rtab) {
1779 rtab = xchg(&cl->R_tab, rtab); 1780 qdisc_put_rtab(cl->R_tab);
1780 qdisc_put_rtab(rtab); 1781 cl->R_tab = rtab;
1781 } 1782 }
1782 1783
1783 if (tb[TCA_CBQ_LSSOPT]) 1784 if (tb[TCA_CBQ_LSSOPT])
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index e71a5de23e23..8d523d9b636c 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -208,7 +208,8 @@ static int drr_graft_class(struct Qdisc *sch, unsigned long arg,
208 208
209 sch_tree_lock(sch); 209 sch_tree_lock(sch);
210 drr_purge_queue(cl); 210 drr_purge_queue(cl);
211 *old = xchg(&cl->qdisc, new); 211 *old = cl->qdisc;
212 cl->qdisc = new;
212 sch_tree_unlock(sch); 213 sch_tree_unlock(sch);
213 return 0; 214 return 0;
214} 215}
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 3f9427a4b757..d303daa45d49 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -68,7 +68,8 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
68 } 68 }
69 69
70 sch_tree_lock(sch); 70 sch_tree_lock(sch);
71 *old = xchg(&p->q, new); 71 *old = p->q;
72 p->q = new;
72 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); 73 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
73 qdisc_reset(*old); 74 qdisc_reset(*old);
74 sch_tree_unlock(sch); 75 sch_tree_unlock(sch);
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 071c4749a12b..51dd3f401623 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1202,7 +1202,8 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1202 1202
1203 sch_tree_lock(sch); 1203 sch_tree_lock(sch);
1204 hfsc_purge_queue(sch, cl); 1204 hfsc_purge_queue(sch, cl);
1205 *old = xchg(&cl->qdisc, new); 1205 *old = cl->qdisc;
1206 cl->qdisc = new;
1206 sch_tree_unlock(sch); 1207 sch_tree_unlock(sch);
1207 return 0; 1208 return 0;
1208} 1209}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 83f5e69243c1..3a119f576bb3 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1100,7 +1100,9 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1100 == NULL) 1100 == NULL)
1101 return -ENOBUFS; 1101 return -ENOBUFS;
1102 sch_tree_lock(sch); 1102 sch_tree_lock(sch);
1103 if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { 1103 *old = cl->un.leaf.q;
1104 cl->un.leaf.q = new;
1105 if (*old != NULL) {
1104 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); 1106 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1105 qdisc_reset(*old); 1107 qdisc_reset(*old);
1106 } 1108 }
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index f645ac55a1a1..7e151861794b 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -214,7 +214,8 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
214 q->bands = qopt->bands; 214 q->bands = qopt->bands;
215 for (i = q->bands; i < q->max_bands; i++) { 215 for (i = q->bands; i < q->max_bands; i++) {
216 if (q->queues[i] != &noop_qdisc) { 216 if (q->queues[i] != &noop_qdisc) {
217 struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc); 217 struct Qdisc *child = q->queues[i];
218 q->queues[i] = &noop_qdisc;
218 qdisc_tree_decrease_qlen(child, child->q.qlen); 219 qdisc_tree_decrease_qlen(child, child->q.qlen);
219 qdisc_destroy(child); 220 qdisc_destroy(child);
220 } 221 }
@@ -224,7 +225,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
224 225
225 for (i = 0; i < q->bands; i++) { 226 for (i = 0; i < q->bands; i++) {
226 if (q->queues[i] == &noop_qdisc) { 227 if (q->queues[i] == &noop_qdisc) {
227 struct Qdisc *child; 228 struct Qdisc *child, *old;
228 child = qdisc_create_dflt(qdisc_dev(sch), 229 child = qdisc_create_dflt(qdisc_dev(sch),
229 sch->dev_queue, 230 sch->dev_queue,
230 &pfifo_qdisc_ops, 231 &pfifo_qdisc_ops,
@@ -232,12 +233,13 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
232 i + 1)); 233 i + 1));
233 if (child) { 234 if (child) {
234 sch_tree_lock(sch); 235 sch_tree_lock(sch);
235 child = xchg(&q->queues[i], child); 236 old = q->queues[i];
237 q->queues[i] = child;
236 238
237 if (child != &noop_qdisc) { 239 if (old != &noop_qdisc) {
238 qdisc_tree_decrease_qlen(child, 240 qdisc_tree_decrease_qlen(old,
239 child->q.qlen); 241 old->q.qlen);
240 qdisc_destroy(child); 242 qdisc_destroy(old);
241 } 243 }
242 sch_tree_unlock(sch); 244 sch_tree_unlock(sch);
243 } 245 }
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 3cbc3ff7b5bc..f840d6b27c65 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -331,10 +331,9 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
331 root_lock = qdisc_root_sleeping_lock(sch); 331 root_lock = qdisc_root_sleeping_lock(sch);
332 332
333 spin_lock_bh(root_lock); 333 spin_lock_bh(root_lock);
334 d = xchg(&q->delay_dist, d); 334 kfree(q->delay_dist);
335 q->delay_dist = d;
335 spin_unlock_bh(root_lock); 336 spin_unlock_bh(root_lock);
336
337 kfree(d);
338 return 0; 337 return 0;
339} 338}
340 339
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index ea65a87ec22c..94cecef70145 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -187,7 +187,8 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
187 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); 187 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
188 188
189 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) { 189 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
190 struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc); 190 struct Qdisc *child = q->queues[i];
191 q->queues[i] = &noop_qdisc;
191 if (child != &noop_qdisc) { 192 if (child != &noop_qdisc) {
192 qdisc_tree_decrease_qlen(child, child->q.qlen); 193 qdisc_tree_decrease_qlen(child, child->q.qlen);
193 qdisc_destroy(child); 194 qdisc_destroy(child);
@@ -197,18 +198,19 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
197 198
198 for (i=0; i<q->bands; i++) { 199 for (i=0; i<q->bands; i++) {
199 if (q->queues[i] == &noop_qdisc) { 200 if (q->queues[i] == &noop_qdisc) {
200 struct Qdisc *child; 201 struct Qdisc *child, *old;
201 child = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, 202 child = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
202 &pfifo_qdisc_ops, 203 &pfifo_qdisc_ops,
203 TC_H_MAKE(sch->handle, i + 1)); 204 TC_H_MAKE(sch->handle, i + 1));
204 if (child) { 205 if (child) {
205 sch_tree_lock(sch); 206 sch_tree_lock(sch);
206 child = xchg(&q->queues[i], child); 207 old = q->queues[i];
208 q->queues[i] = child;
207 209
208 if (child != &noop_qdisc) { 210 if (old != &noop_qdisc) {
209 qdisc_tree_decrease_qlen(child, 211 qdisc_tree_decrease_qlen(old,
210 child->q.qlen); 212 old->q.qlen);
211 qdisc_destroy(child); 213 qdisc_destroy(old);
212 } 214 }
213 sch_tree_unlock(sch); 215 sch_tree_unlock(sch);
214 } 216 }
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 6a0371c22643..2bdf241f6315 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -202,7 +202,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
202 q->limit = ctl->limit; 202 q->limit = ctl->limit;
203 if (child) { 203 if (child) {
204 qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); 204 qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
205 qdisc_destroy(xchg(&q->qdisc, child)); 205 qdisc_destroy(q->qdisc);
206 q->qdisc = child;
206 } 207 }
207 208
208 red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, 209 red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
@@ -283,7 +284,8 @@ static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
283 new = &noop_qdisc; 284 new = &noop_qdisc;
284 285
285 sch_tree_lock(sch); 286 sch_tree_lock(sch);
286 *old = xchg(&q->qdisc, new); 287 *old = q->qdisc;
288 q->qdisc = new;
287 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); 289 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
288 qdisc_reset(*old); 290 qdisc_reset(*old);
289 sch_tree_unlock(sch); 291 sch_tree_unlock(sch);
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index bb7783d584bb..a2f93c09f3cc 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -236,6 +236,7 @@ static int tbf_change(struct Qdisc* sch, struct nlattr *opt)
236 struct tc_tbf_qopt *qopt; 236 struct tc_tbf_qopt *qopt;
237 struct qdisc_rate_table *rtab = NULL; 237 struct qdisc_rate_table *rtab = NULL;
238 struct qdisc_rate_table *ptab = NULL; 238 struct qdisc_rate_table *ptab = NULL;
239 struct qdisc_rate_table *tmp;
239 struct Qdisc *child = NULL; 240 struct Qdisc *child = NULL;
240 int max_size,n; 241 int max_size,n;
241 242
@@ -284,7 +285,8 @@ static int tbf_change(struct Qdisc* sch, struct nlattr *opt)
284 sch_tree_lock(sch); 285 sch_tree_lock(sch);
285 if (child) { 286 if (child) {
286 qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); 287 qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
287 qdisc_destroy(xchg(&q->qdisc, child)); 288 qdisc_destroy(q->qdisc);
289 q->qdisc = child;
288 } 290 }
289 q->limit = qopt->limit; 291 q->limit = qopt->limit;
290 q->mtu = qopt->mtu; 292 q->mtu = qopt->mtu;
@@ -292,8 +294,14 @@ static int tbf_change(struct Qdisc* sch, struct nlattr *opt)
292 q->buffer = qopt->buffer; 294 q->buffer = qopt->buffer;
293 q->tokens = q->buffer; 295 q->tokens = q->buffer;
294 q->ptokens = q->mtu; 296 q->ptokens = q->mtu;
295 rtab = xchg(&q->R_tab, rtab); 297
296 ptab = xchg(&q->P_tab, ptab); 298 tmp = q->R_tab;
299 q->R_tab = rtab;
300 rtab = tmp;
301
302 tmp = q->P_tab;
303 q->P_tab = ptab;
304 ptab = tmp;
297 sch_tree_unlock(sch); 305 sch_tree_unlock(sch);
298 err = 0; 306 err = 0;
299done: 307done:
@@ -383,7 +391,8 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
383 new = &noop_qdisc; 391 new = &noop_qdisc;
384 392
385 sch_tree_lock(sch); 393 sch_tree_lock(sch);
386 *old = xchg(&q->qdisc, new); 394 *old = q->qdisc;
395 q->qdisc = new;
387 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); 396 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
388 qdisc_reset(*old); 397 qdisc_reset(*old);
389 sch_tree_unlock(sch); 398 sch_tree_unlock(sch);