aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sch_generic.h10
-rw-r--r--net/sched/sch_api.c18
-rw-r--r--net/sched/sch_atm.c17
-rw-r--r--net/sched/sch_cbq.c14
-rw-r--r--net/sched/sch_dsmark.c8
-rw-r--r--net/sched/sch_hfsc.c13
-rw-r--r--net/sched/sch_htb.c14
-rw-r--r--net/sched/sch_ingress.c7
-rw-r--r--net/sched/sch_prio.c7
9 files changed, 30 insertions, 78 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index a3f4ddd1d6a8..1b8e35197ebe 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -177,14 +177,8 @@ extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
177extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); 177extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
178extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, 178extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
179 struct Qdisc_ops *ops, u32 parentid); 179 struct Qdisc_ops *ops, u32 parentid);
180 180extern void tcf_destroy(struct tcf_proto *tp);
181static inline void 181extern void tcf_destroy_chain(struct tcf_proto *fl);
182tcf_destroy(struct tcf_proto *tp)
183{
184 tp->ops->destroy(tp);
185 module_put(tp->ops->owner);
186 kfree(tp);
187}
188 182
189static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch, 183static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
190 struct sk_buff_head *list) 184 struct sk_buff_head *list)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 58732509160d..5b5bce0694e2 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1220,6 +1220,24 @@ reclassify:
1220 return -1; 1220 return -1;
1221} 1221}
1222 1222
1223void tcf_destroy(struct tcf_proto *tp)
1224{
1225 tp->ops->destroy(tp);
1226 module_put(tp->ops->owner);
1227 kfree(tp);
1228}
1229
1230void tcf_destroy_chain(struct tcf_proto *fl)
1231{
1232 struct tcf_proto *tp;
1233
1234 while ((tp = fl) != NULL) {
1235 fl = tp->next;
1236 tcf_destroy(tp);
1237 }
1238}
1239EXPORT_SYMBOL(tcf_destroy_chain);
1240
1223#ifdef CONFIG_PROC_FS 1241#ifdef CONFIG_PROC_FS
1224static int psched_show(struct seq_file *seq, void *v) 1242static int psched_show(struct seq_file *seq, void *v)
1225{ 1243{
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 0cc3c9b72728..be7d299acd73 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -158,19 +158,6 @@ static unsigned long atm_tc_bind_filter(struct Qdisc *sch,
158 return atm_tc_get(sch,classid); 158 return atm_tc_get(sch,classid);
159} 159}
160 160
161
162static void destroy_filters(struct atm_flow_data *flow)
163{
164 struct tcf_proto *filter;
165
166 while ((filter = flow->filter_list)) {
167 DPRINTK("destroy_filters: destroying filter %p\n",filter);
168 flow->filter_list = filter->next;
169 tcf_destroy(filter);
170 }
171}
172
173
174/* 161/*
175 * atm_tc_put handles all destructions, including the ones that are explicitly 162 * atm_tc_put handles all destructions, including the ones that are explicitly
176 * requested (atm_tc_destroy, etc.). The assumption here is that we never drop 163 * requested (atm_tc_destroy, etc.). The assumption here is that we never drop
@@ -195,7 +182,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
195 *prev = flow->next; 182 *prev = flow->next;
196 DPRINTK("atm_tc_put: qdisc %p\n",flow->q); 183 DPRINTK("atm_tc_put: qdisc %p\n",flow->q);
197 qdisc_destroy(flow->q); 184 qdisc_destroy(flow->q);
198 destroy_filters(flow); 185 tcf_destroy_chain(flow->filter_list);
199 if (flow->sock) { 186 if (flow->sock) {
200 DPRINTK("atm_tc_put: f_count %d\n", 187 DPRINTK("atm_tc_put: f_count %d\n",
201 file_count(flow->sock->file)); 188 file_count(flow->sock->file));
@@ -611,7 +598,7 @@ static void atm_tc_destroy(struct Qdisc *sch)
611 DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p); 598 DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p);
612 /* races ? */ 599 /* races ? */
613 while ((flow = p->flows)) { 600 while ((flow = p->flows)) {
614 destroy_filters(flow); 601 tcf_destroy_chain(flow->filter_list);
615 if (flow->ref > 1) 602 if (flow->ref > 1)
616 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, 603 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
617 flow->ref); 604 flow->ref);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 414a97c962f1..a294542cb8e4 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1717,23 +1717,13 @@ static unsigned long cbq_get(struct Qdisc *sch, u32 classid)
1717 return 0; 1717 return 0;
1718} 1718}
1719 1719
1720static void cbq_destroy_filters(struct cbq_class *cl)
1721{
1722 struct tcf_proto *tp;
1723
1724 while ((tp = cl->filter_list) != NULL) {
1725 cl->filter_list = tp->next;
1726 tcf_destroy(tp);
1727 }
1728}
1729
1730static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) 1720static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
1731{ 1721{
1732 struct cbq_sched_data *q = qdisc_priv(sch); 1722 struct cbq_sched_data *q = qdisc_priv(sch);
1733 1723
1734 BUG_TRAP(!cl->filters); 1724 BUG_TRAP(!cl->filters);
1735 1725
1736 cbq_destroy_filters(cl); 1726 tcf_destroy_chain(cl->filter_list);
1737 qdisc_destroy(cl->q); 1727 qdisc_destroy(cl->q);
1738 qdisc_put_rtab(cl->R_tab); 1728 qdisc_put_rtab(cl->R_tab);
1739#ifdef CONFIG_NET_ESTIMATOR 1729#ifdef CONFIG_NET_ESTIMATOR
@@ -1760,7 +1750,7 @@ cbq_destroy(struct Qdisc* sch)
1760 */ 1750 */
1761 for (h = 0; h < 16; h++) 1751 for (h = 0; h < 16; h++)
1762 for (cl = q->classes[h]; cl; cl = cl->next) 1752 for (cl = q->classes[h]; cl; cl = cl->next)
1763 cbq_destroy_filters(cl); 1753 tcf_destroy_chain(cl->filter_list);
1764 1754
1765 for (h = 0; h < 16; h++) { 1755 for (h = 0; h < 16; h++) {
1766 struct cbq_class *next; 1756 struct cbq_class *next;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 2c857af79a1e..e38e0d00d1e6 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -412,16 +412,10 @@ static void dsmark_reset(struct Qdisc *sch)
412static void dsmark_destroy(struct Qdisc *sch) 412static void dsmark_destroy(struct Qdisc *sch)
413{ 413{
414 struct dsmark_qdisc_data *p = PRIV(sch); 414 struct dsmark_qdisc_data *p = PRIV(sch);
415 struct tcf_proto *tp;
416 415
417 DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); 416 DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
418 417
419 while (p->filter_list) { 418 tcf_destroy_chain(p->filter_list);
420 tp = p->filter_list;
421 p->filter_list = tp->next;
422 tcf_destroy(tp);
423 }
424
425 qdisc_destroy(p->q); 419 qdisc_destroy(p->q);
426 kfree(p->mask); 420 kfree(p->mask);
427} 421}
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 7d51d0d6a70e..9d124c4ee3a7 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1122,22 +1122,11 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1122} 1122}
1123 1123
1124static void 1124static void
1125hfsc_destroy_filters(struct tcf_proto **fl)
1126{
1127 struct tcf_proto *tp;
1128
1129 while ((tp = *fl) != NULL) {
1130 *fl = tp->next;
1131 tcf_destroy(tp);
1132 }
1133}
1134
1135static void
1136hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) 1125hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
1137{ 1126{
1138 struct hfsc_sched *q = qdisc_priv(sch); 1127 struct hfsc_sched *q = qdisc_priv(sch);
1139 1128
1140 hfsc_destroy_filters(&cl->filter_list); 1129 tcf_destroy_chain(cl->filter_list);
1141 qdisc_destroy(cl->qdisc); 1130 qdisc_destroy(cl->qdisc);
1142#ifdef CONFIG_NET_ESTIMATOR 1131#ifdef CONFIG_NET_ESTIMATOR
1143 gen_kill_estimator(&cl->bstats, &cl->rate_est); 1132 gen_kill_estimator(&cl->bstats, &cl->rate_est);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 3f528554b0d4..99bcec8dd04c 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1236,16 +1236,6 @@ static unsigned long htb_get(struct Qdisc *sch, u32 classid)
1236 return (unsigned long)cl; 1236 return (unsigned long)cl;
1237} 1237}
1238 1238
1239static void htb_destroy_filters(struct tcf_proto **fl)
1240{
1241 struct tcf_proto *tp;
1242
1243 while ((tp = *fl) != NULL) {
1244 *fl = tp->next;
1245 tcf_destroy(tp);
1246 }
1247}
1248
1249static inline int htb_parent_last_child(struct htb_class *cl) 1239static inline int htb_parent_last_child(struct htb_class *cl)
1250{ 1240{
1251 if (!cl->parent) 1241 if (!cl->parent)
@@ -1289,7 +1279,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
1289 qdisc_put_rtab(cl->rate); 1279 qdisc_put_rtab(cl->rate);
1290 qdisc_put_rtab(cl->ceil); 1280 qdisc_put_rtab(cl->ceil);
1291 1281
1292 htb_destroy_filters(&cl->filter_list); 1282 tcf_destroy_chain(cl->filter_list);
1293 1283
1294 while (!list_empty(&cl->children)) 1284 while (!list_empty(&cl->children))
1295 htb_destroy_class(sch, list_entry(cl->children.next, 1285 htb_destroy_class(sch, list_entry(cl->children.next,
@@ -1321,7 +1311,7 @@ static void htb_destroy(struct Qdisc *sch)
1321 and surprisingly it worked in 2.4. But it must precede it 1311 and surprisingly it worked in 2.4. But it must precede it
1322 because filter need its target class alive to be able to call 1312 because filter need its target class alive to be able to call
1323 unbind_filter on it (without Oops). */ 1313 unbind_filter on it (without Oops). */
1324 htb_destroy_filters(&q->filter_list); 1314 tcf_destroy_chain(q->filter_list);
1325 1315
1326 while (!list_empty(&q->root)) 1316 while (!list_empty(&q->root))
1327 htb_destroy_class(sch, list_entry(q->root.next, 1317 htb_destroy_class(sch, list_entry(q->root.next,
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index f63d5c6eb302..1fb60aba1e6c 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -346,14 +346,9 @@ static void ingress_reset(struct Qdisc *sch)
346static void ingress_destroy(struct Qdisc *sch) 346static void ingress_destroy(struct Qdisc *sch)
347{ 347{
348 struct ingress_qdisc_data *p = PRIV(sch); 348 struct ingress_qdisc_data *p = PRIV(sch);
349 struct tcf_proto *tp;
350 349
351 DPRINTK("ingress_destroy(sch %p,[qdisc %p])\n", sch, p); 350 DPRINTK("ingress_destroy(sch %p,[qdisc %p])\n", sch, p);
352 while (p->filter_list) { 351 tcf_destroy_chain(p->filter_list);
353 tp = p->filter_list;
354 p->filter_list = tp->next;
355 tcf_destroy(tp);
356 }
357#if 0 352#if 0
358/* for future use */ 353/* for future use */
359 qdisc_destroy(p->q); 354 qdisc_destroy(p->q);
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index f13996348dda..5cfe60bf6e25 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -189,13 +189,8 @@ prio_destroy(struct Qdisc* sch)
189{ 189{
190 int prio; 190 int prio;
191 struct prio_sched_data *q = qdisc_priv(sch); 191 struct prio_sched_data *q = qdisc_priv(sch);
192 struct tcf_proto *tp;
193
194 while ((tp = q->filter_list) != NULL) {
195 q->filter_list = tp->next;
196 tcf_destroy(tp);
197 }
198 192
193 tcf_destroy_chain(q->filter_list);
199 for (prio=0; prio<q->bands; prio++) 194 for (prio=0; prio<q->bands; prio++)
200 qdisc_destroy(q->queues[prio]); 195 qdisc_destroy(q->queues[prio]);
201} 196}