Commit a48b5a61 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NET_SCHED]: Unline tcf_destroy

Uninline tcf_destroy and add a helper function to destroy an entire filter
chain.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3bebcda2
...@@ -177,14 +177,8 @@ extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n); ...@@ -177,14 +177,8 @@ extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
struct Qdisc_ops *ops, u32 parentid); struct Qdisc_ops *ops, u32 parentid);
extern void tcf_destroy(struct tcf_proto *tp);
static inline void extern void tcf_destroy_chain(struct tcf_proto *fl);
tcf_destroy(struct tcf_proto *tp)
{
tp->ops->destroy(tp);
module_put(tp->ops->owner);
kfree(tp);
}
static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch, static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff_head *list) struct sk_buff_head *list)
......
...@@ -1220,6 +1220,24 @@ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, ...@@ -1220,6 +1220,24 @@ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
return -1; return -1;
} }
void tcf_destroy(struct tcf_proto *tp)
{
tp->ops->destroy(tp);
module_put(tp->ops->owner);
kfree(tp);
}
void tcf_destroy_chain(struct tcf_proto *fl)
{
struct tcf_proto *tp;
while ((tp = fl) != NULL) {
fl = tp->next;
tcf_destroy(tp);
}
}
EXPORT_SYMBOL(tcf_destroy_chain);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static int psched_show(struct seq_file *seq, void *v) static int psched_show(struct seq_file *seq, void *v)
{ {
......
...@@ -158,19 +158,6 @@ static unsigned long atm_tc_bind_filter(struct Qdisc *sch, ...@@ -158,19 +158,6 @@ static unsigned long atm_tc_bind_filter(struct Qdisc *sch,
return atm_tc_get(sch,classid); return atm_tc_get(sch,classid);
} }
static void destroy_filters(struct atm_flow_data *flow)
{
struct tcf_proto *filter;
while ((filter = flow->filter_list)) {
DPRINTK("destroy_filters: destroying filter %p\n",filter);
flow->filter_list = filter->next;
tcf_destroy(filter);
}
}
/* /*
* atm_tc_put handles all destructions, including the ones that are explicitly * atm_tc_put handles all destructions, including the ones that are explicitly
* requested (atm_tc_destroy, etc.). The assumption here is that we never drop * 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,7 +182,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
*prev = flow->next; *prev = flow->next;
DPRINTK("atm_tc_put: qdisc %p\n",flow->q); DPRINTK("atm_tc_put: qdisc %p\n",flow->q);
qdisc_destroy(flow->q); qdisc_destroy(flow->q);
destroy_filters(flow); tcf_destroy_chain(flow->filter_list);
if (flow->sock) { if (flow->sock) {
DPRINTK("atm_tc_put: f_count %d\n", DPRINTK("atm_tc_put: f_count %d\n",
file_count(flow->sock->file)); file_count(flow->sock->file));
...@@ -611,7 +598,7 @@ static void atm_tc_destroy(struct Qdisc *sch) ...@@ -611,7 +598,7 @@ static void atm_tc_destroy(struct Qdisc *sch)
DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p); DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p);
/* races ? */ /* races ? */
while ((flow = p->flows)) { while ((flow = p->flows)) {
destroy_filters(flow); tcf_destroy_chain(flow->filter_list);
if (flow->ref > 1) if (flow->ref > 1)
printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
flow->ref); flow->ref);
......
...@@ -1717,23 +1717,13 @@ static unsigned long cbq_get(struct Qdisc *sch, u32 classid) ...@@ -1717,23 +1717,13 @@ static unsigned long cbq_get(struct Qdisc *sch, u32 classid)
return 0; return 0;
} }
static void cbq_destroy_filters(struct cbq_class *cl)
{
struct tcf_proto *tp;
while ((tp = cl->filter_list) != NULL) {
cl->filter_list = tp->next;
tcf_destroy(tp);
}
}
static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
{ {
struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_sched_data *q = qdisc_priv(sch);
BUG_TRAP(!cl->filters); BUG_TRAP(!cl->filters);
cbq_destroy_filters(cl); tcf_destroy_chain(cl->filter_list);
qdisc_destroy(cl->q); qdisc_destroy(cl->q);
qdisc_put_rtab(cl->R_tab); qdisc_put_rtab(cl->R_tab);
#ifdef CONFIG_NET_ESTIMATOR #ifdef CONFIG_NET_ESTIMATOR
...@@ -1760,7 +1750,7 @@ cbq_destroy(struct Qdisc* sch) ...@@ -1760,7 +1750,7 @@ cbq_destroy(struct Qdisc* sch)
*/ */
for (h = 0; h < 16; h++) for (h = 0; h < 16; h++)
for (cl = q->classes[h]; cl; cl = cl->next) for (cl = q->classes[h]; cl; cl = cl->next)
cbq_destroy_filters(cl); tcf_destroy_chain(cl->filter_list);
for (h = 0; h < 16; h++) { for (h = 0; h < 16; h++) {
struct cbq_class *next; struct cbq_class *next;
......
...@@ -412,16 +412,10 @@ static void dsmark_reset(struct Qdisc *sch) ...@@ -412,16 +412,10 @@ static void dsmark_reset(struct Qdisc *sch)
static void dsmark_destroy(struct Qdisc *sch) static void dsmark_destroy(struct Qdisc *sch)
{ {
struct dsmark_qdisc_data *p = PRIV(sch); struct dsmark_qdisc_data *p = PRIV(sch);
struct tcf_proto *tp;
DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
while (p->filter_list) { tcf_destroy_chain(p->filter_list);
tp = p->filter_list;
p->filter_list = tp->next;
tcf_destroy(tp);
}
qdisc_destroy(p->q); qdisc_destroy(p->q);
kfree(p->mask); kfree(p->mask);
} }
......
...@@ -1121,23 +1121,12 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, ...@@ -1121,23 +1121,12 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
return 0; return 0;
} }
static void
hfsc_destroy_filters(struct tcf_proto **fl)
{
struct tcf_proto *tp;
while ((tp = *fl) != NULL) {
*fl = tp->next;
tcf_destroy(tp);
}
}
static void static void
hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
{ {
struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_sched *q = qdisc_priv(sch);
hfsc_destroy_filters(&cl->filter_list); tcf_destroy_chain(cl->filter_list);
qdisc_destroy(cl->qdisc); qdisc_destroy(cl->qdisc);
#ifdef CONFIG_NET_ESTIMATOR #ifdef CONFIG_NET_ESTIMATOR
gen_kill_estimator(&cl->bstats, &cl->rate_est); gen_kill_estimator(&cl->bstats, &cl->rate_est);
......
...@@ -1236,16 +1236,6 @@ static unsigned long htb_get(struct Qdisc *sch, u32 classid) ...@@ -1236,16 +1236,6 @@ static unsigned long htb_get(struct Qdisc *sch, u32 classid)
return (unsigned long)cl; return (unsigned long)cl;
} }
static void htb_destroy_filters(struct tcf_proto **fl)
{
struct tcf_proto *tp;
while ((tp = *fl) != NULL) {
*fl = tp->next;
tcf_destroy(tp);
}
}
static inline int htb_parent_last_child(struct htb_class *cl) static inline int htb_parent_last_child(struct htb_class *cl)
{ {
if (!cl->parent) if (!cl->parent)
...@@ -1289,7 +1279,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) ...@@ -1289,7 +1279,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
qdisc_put_rtab(cl->rate); qdisc_put_rtab(cl->rate);
qdisc_put_rtab(cl->ceil); qdisc_put_rtab(cl->ceil);
htb_destroy_filters(&cl->filter_list); tcf_destroy_chain(cl->filter_list);
while (!list_empty(&cl->children)) while (!list_empty(&cl->children))
htb_destroy_class(sch, list_entry(cl->children.next, htb_destroy_class(sch, list_entry(cl->children.next,
...@@ -1321,7 +1311,7 @@ static void htb_destroy(struct Qdisc *sch) ...@@ -1321,7 +1311,7 @@ static void htb_destroy(struct Qdisc *sch)
and surprisingly it worked in 2.4. But it must precede it and surprisingly it worked in 2.4. But it must precede it
because filter need its target class alive to be able to call because filter need its target class alive to be able to call
unbind_filter on it (without Oops). */ unbind_filter on it (without Oops). */
htb_destroy_filters(&q->filter_list); tcf_destroy_chain(q->filter_list);
while (!list_empty(&q->root)) while (!list_empty(&q->root))
htb_destroy_class(sch, list_entry(q->root.next, htb_destroy_class(sch, list_entry(q->root.next,
......
...@@ -346,14 +346,9 @@ static void ingress_reset(struct Qdisc *sch) ...@@ -346,14 +346,9 @@ static void ingress_reset(struct Qdisc *sch)
static void ingress_destroy(struct Qdisc *sch) static void ingress_destroy(struct Qdisc *sch)
{ {
struct ingress_qdisc_data *p = PRIV(sch); struct ingress_qdisc_data *p = PRIV(sch);
struct tcf_proto *tp;
DPRINTK("ingress_destroy(sch %p,[qdisc %p])\n", sch, p); DPRINTK("ingress_destroy(sch %p,[qdisc %p])\n", sch, p);
while (p->filter_list) { tcf_destroy_chain(p->filter_list);
tp = p->filter_list;
p->filter_list = tp->next;
tcf_destroy(tp);
}
#if 0 #if 0
/* for future use */ /* for future use */
qdisc_destroy(p->q); qdisc_destroy(p->q);
......
...@@ -189,13 +189,8 @@ prio_destroy(struct Qdisc* sch) ...@@ -189,13 +189,8 @@ prio_destroy(struct Qdisc* sch)
{ {
int prio; int prio;
struct prio_sched_data *q = qdisc_priv(sch); struct prio_sched_data *q = qdisc_priv(sch);
struct tcf_proto *tp;
while ((tp = q->filter_list) != NULL) {
q->filter_list = tp->next;
tcf_destroy(tp);
}
tcf_destroy_chain(q->filter_list);
for (prio=0; prio<q->bands; prio++) for (prio=0; prio<q->bands; prio++)
qdisc_destroy(q->queues[prio]); qdisc_destroy(q->queues[prio]);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment