Commit 3f0ccc08 authored by David S. Miller's avatar David S. Miller

[PKT_SCHED]: Proper module refcounting for packet schedulers.

parent 8a7cd77d
......@@ -49,6 +49,8 @@ struct Qdisc_class_ops
int (*dump)(struct Qdisc *, unsigned long, struct sk_buff *skb, struct tcmsg*);
};
struct module;
struct Qdisc_ops
{
struct Qdisc_ops *next;
......@@ -67,6 +69,8 @@ struct Qdisc_ops
int (*change)(struct Qdisc *, struct rtattr *arg);
int (*dump)(struct Qdisc *, struct sk_buff *);
struct module *owner;
};
extern rwlock_t qdisc_tree_lock;
......
......@@ -16,6 +16,7 @@
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
......@@ -447,6 +448,10 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
else
sch->handle = handle;
err = -EBUSY;
if (!try_module_get(ops->owner))
goto err_out;
if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
write_lock(&qdisc_tree_lock);
sch->next = dev->qdisc_list;
......@@ -458,6 +463,7 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
#endif
return sch;
}
module_put(ops->owner);
err_out:
*errp = err;
......
......@@ -575,7 +575,6 @@ static int atm_tc_init(struct Qdisc *sch,struct rtattr *opt)
p->link.ref = 1;
p->link.next = NULL;
tasklet_init(&p->task,sch_atm_dequeue,(unsigned long) sch);
MOD_INC_USE_COUNT;
return 0;
}
......@@ -612,7 +611,6 @@ static void atm_tc_destroy(struct Qdisc *sch)
}
}
tasklet_kill(&p->task);
MOD_DEC_USE_COUNT;
}
......@@ -663,41 +661,35 @@ static int atm_tc_dump(struct Qdisc *sch, struct sk_buff *skb)
return 0;
}
static struct Qdisc_class_ops atm_class_ops =
{
.graft = atm_tc_graft,
.leaf = atm_tc_leaf,
.get = atm_tc_get,
.put = atm_tc_put,
.change = atm_tc_change,
.delete = atm_tc_delete,
.walk = atm_tc_walk,
.tcf_chain = atm_tc_find_tcf,
.bind_tcf = atm_tc_bind_filter,
.unbind_tcf = atm_tc_put,
.dump = atm_tc_dump_class,
static struct Qdisc_class_ops atm_class_ops = {
.graft = atm_tc_graft,
.leaf = atm_tc_leaf,
.get = atm_tc_get,
.put = atm_tc_put,
.change = atm_tc_change,
.delete = atm_tc_delete,
.walk = atm_tc_walk,
.tcf_chain = atm_tc_find_tcf,
.bind_tcf = atm_tc_bind_filter,
.unbind_tcf = atm_tc_put,
.dump = atm_tc_dump_class,
};
struct Qdisc_ops atm_qdisc_ops =
{
.next = NULL,
.cl_ops = &atm_class_ops,
.id = "atm",
.priv_size = sizeof(struct atm_qdisc_data),
.enqueue = atm_tc_enqueue,
.dequeue = atm_tc_dequeue,
.requeue = atm_tc_requeue,
.drop = atm_tc_drop,
.init = atm_tc_init,
.reset = atm_tc_reset,
.destroy = atm_tc_destroy,
.change = NULL,
.dump = atm_tc_dump
struct Qdisc_ops atm_qdisc_ops = {
.next = NULL,
.cl_ops = &atm_class_ops,
.id = "atm",
.priv_size = sizeof(struct atm_qdisc_data),
.enqueue = atm_tc_enqueue,
.dequeue = atm_tc_dequeue,
.requeue = atm_tc_requeue,
.drop = atm_tc_drop,
.init = atm_tc_init,
.reset = atm_tc_reset,
.destroy = atm_tc_destroy,
.change = NULL,
.dump = atm_tc_dump,
.owner = THIS_MODULE,
};
......
......@@ -1411,11 +1411,8 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
r = RTA_DATA(tb[TCA_CBQ_RATE-1]);
MOD_INC_USE_COUNT;
if ((q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB-1])) == NULL) {
MOD_DEC_USE_COUNT;
if ((q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB-1])) == NULL)
return -EINVAL;
}
q->link.refcnt = 1;
q->link.sibling = &q->link;
......@@ -1749,7 +1746,6 @@ cbq_destroy(struct Qdisc* sch)
}
qdisc_put_rtab(q->link.R_tab);
MOD_DEC_USE_COUNT;
}
static void cbq_put(struct Qdisc *sch, unsigned long arg)
......@@ -2064,41 +2060,35 @@ static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
}
}
static struct Qdisc_class_ops cbq_class_ops =
{
.graft = cbq_graft,
.leaf = cbq_leaf,
.get = cbq_get,
.put = cbq_put,
.change = cbq_change_class,
.delete = cbq_delete,
.walk = cbq_walk,
.tcf_chain = cbq_find_tcf,
.bind_tcf = cbq_bind_filter,
.unbind_tcf = cbq_unbind_filter,
.dump = cbq_dump_class,
static struct Qdisc_class_ops cbq_class_ops = {
.graft = cbq_graft,
.leaf = cbq_leaf,
.get = cbq_get,
.put = cbq_put,
.change = cbq_change_class,
.delete = cbq_delete,
.walk = cbq_walk,
.tcf_chain = cbq_find_tcf,
.bind_tcf = cbq_bind_filter,
.unbind_tcf = cbq_unbind_filter,
.dump = cbq_dump_class,
};
struct Qdisc_ops cbq_qdisc_ops =
{
.next = NULL,
.cl_ops = &cbq_class_ops,
.id = "cbq",
.priv_size = sizeof(struct cbq_sched_data),
.enqueue = cbq_enqueue,
.dequeue = cbq_dequeue,
.requeue = cbq_requeue,
.drop = cbq_drop,
.init = cbq_init,
.reset = cbq_reset,
.destroy = cbq_destroy,
.change = NULL,
.dump = cbq_dump,
struct Qdisc_ops cbq_qdisc_ops = {
.next = NULL,
.cl_ops = &cbq_class_ops,
.id = "cbq",
.priv_size = sizeof(struct cbq_sched_data),
.enqueue = cbq_enqueue,
.dequeue = cbq_dequeue,
.requeue = cbq_requeue,
.drop = cbq_drop,
.init = cbq_init,
.reset = cbq_reset,
.destroy = cbq_destroy,
.change = NULL,
.dump = cbq_dump,
.owner = THIS_MODULE,
};
#ifdef MODULE
......
......@@ -756,8 +756,6 @@ csz_destroy(struct Qdisc* sch)
q->filter_list = tp->next;
tp->ops->destroy(tp);
}
MOD_DEC_USE_COUNT;
}
static int csz_init(struct Qdisc *sch, struct rtattr *opt)
......@@ -799,7 +797,6 @@ static int csz_init(struct Qdisc *sch, struct rtattr *opt)
q->wd_timer.data = (unsigned long)sch;
q->wd_timer.function = csz_watchdog;
#endif
MOD_INC_USE_COUNT;
return 0;
}
......@@ -1018,42 +1015,35 @@ static struct tcf_proto ** csz_find_tcf(struct Qdisc *sch, unsigned long cl)
return &q->filter_list;
}
struct Qdisc_class_ops csz_class_ops =
{
.graft = csz_graft,
.leaf = csz_leaf,
.get = csz_get,
.put = csz_put,
.change = csz_change,
.delete = csz_delete,
.walk = csz_walk,
.tcf_chain = csz_find_tcf,
.bind_tcf = csz_bind,
.unbind_tcf = csz_put,
.dump = csz_dump_class,
struct Qdisc_class_ops csz_class_ops = {
.graft = csz_graft,
.leaf = csz_leaf,
.get = csz_get,
.put = csz_put,
.change = csz_change,
.delete = csz_delete,
.walk = csz_walk,
.tcf_chain = csz_find_tcf,
.bind_tcf = csz_bind,
.unbind_tcf = csz_put,
.dump = csz_dump_class,
};
struct Qdisc_ops csz_qdisc_ops =
{
.next = NULL,
.cl_ops = &csz_class_ops,
.id = "csz",
.priv_size = sizeof(struct csz_sched_data),
.enqueue = csz_enqueue,
.dequeue = csz_dequeue,
.requeue = NULL,
.drop = NULL,
.init = csz_init,
.reset = csz_reset,
.destroy = csz_destroy,
.change = NULL,
.dump = csz_dump,
struct Qdisc_ops csz_qdisc_ops = {
.next = NULL,
.cl_ops = &csz_class_ops,
.id = "csz",
.priv_size = sizeof(struct csz_sched_data),
.enqueue = csz_enqueue,
.dequeue = csz_dequeue,
.requeue = NULL,
.drop = NULL,
.init = csz_init,
.reset = csz_reset,
.destroy = csz_destroy,
.change = NULL,
.dump = csz_dump,
.owner = THIS_MODULE,
};
......
......@@ -353,7 +353,6 @@ int dsmark_init(struct Qdisc *sch,struct rtattr *opt)
if (!(p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
p->q = &noop_qdisc;
DPRINTK("dsmark_init: qdisc %p\n",&p->q);
MOD_INC_USE_COUNT;
return 0;
}
......@@ -382,7 +381,6 @@ static void dsmark_destroy(struct Qdisc *sch)
qdisc_destroy(p->q);
p->q = &noop_qdisc;
kfree(p->mask);
MOD_DEC_USE_COUNT;
}
......@@ -433,41 +431,35 @@ static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb)
return -1;
}
static struct Qdisc_class_ops dsmark_class_ops =
{
.graft = dsmark_graft,
.leaf = dsmark_leaf,
.get = dsmark_get,
.put = dsmark_put,
.change = dsmark_change,
.delete = dsmark_delete,
.walk = dsmark_walk,
.tcf_chain = dsmark_find_tcf,
.bind_tcf = dsmark_bind_filter,
.unbind_tcf = dsmark_put,
.dump = dsmark_dump_class,
static struct Qdisc_class_ops dsmark_class_ops = {
.graft = dsmark_graft,
.leaf = dsmark_leaf,
.get = dsmark_get,
.put = dsmark_put,
.change = dsmark_change,
.delete = dsmark_delete,
.walk = dsmark_walk,
.tcf_chain = dsmark_find_tcf,
.bind_tcf = dsmark_bind_filter,
.unbind_tcf = dsmark_put,
.dump = dsmark_dump_class,
};
struct Qdisc_ops dsmark_qdisc_ops =
{
.next = NULL,
.cl_ops = &dsmark_class_ops,
.id = "dsmark",
.priv_size = sizeof(struct dsmark_qdisc_data),
.enqueue = dsmark_enqueue,
.dequeue = dsmark_dequeue,
.requeue = dsmark_requeue,
.drop = dsmark_drop,
.init = dsmark_init,
.reset = dsmark_reset,
.destroy = dsmark_destroy,
.change = NULL,
.dump = dsmark_dump
struct Qdisc_ops dsmark_qdisc_ops = {
.next = NULL,
.cl_ops = &dsmark_class_ops,
.id = "dsmark",
.priv_size = sizeof(struct dsmark_qdisc_data),
.enqueue = dsmark_enqueue,
.dequeue = dsmark_dequeue,
.requeue = dsmark_requeue,
.drop = dsmark_drop,
.init = dsmark_init,
.reset = dsmark_reset,
.destroy = dsmark_destroy,
.change = NULL,
.dump = dsmark_dump,
.owner = THIS_MODULE,
};
#ifdef MODULE
......
......@@ -10,6 +10,7 @@
*/
#include <linux/config.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
......@@ -168,42 +169,36 @@ static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
return -1;
}
struct Qdisc_ops pfifo_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "pfifo",
.priv_size = sizeof(struct fifo_sched_data),
.enqueue = pfifo_enqueue,
.dequeue = pfifo_dequeue,
.requeue = pfifo_requeue,
.drop = fifo_drop,
.init = fifo_init,
.reset = fifo_reset,
.destroy = NULL,
.change = fifo_init,
.dump = fifo_dump,
struct Qdisc_ops pfifo_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "pfifo",
.priv_size = sizeof(struct fifo_sched_data),
.enqueue = pfifo_enqueue,
.dequeue = pfifo_dequeue,
.requeue = pfifo_requeue,
.drop = fifo_drop,
.init = fifo_init,
.reset = fifo_reset,
.destroy = NULL,
.change = fifo_init,
.dump = fifo_dump,
.owner = THIS_MODULE,
};
struct Qdisc_ops bfifo_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "bfifo",
.priv_size = sizeof(struct fifo_sched_data),
.enqueue = bfifo_enqueue,
.dequeue = bfifo_dequeue,
.requeue = bfifo_requeue,
.drop = fifo_drop,
.init = fifo_init,
.reset = fifo_reset,
.destroy = NULL,
.change = fifo_init,
.dump = fifo_dump,
struct Qdisc_ops bfifo_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "bfifo",
.priv_size = sizeof(struct fifo_sched_data),
.enqueue = bfifo_enqueue,
.dequeue = bfifo_dequeue,
.requeue = bfifo_requeue,
.drop = fifo_drop,
.init = fifo_init,
.reset = fifo_reset,
.destroy = NULL,
.change = fifo_init,
.dump = fifo_dump,
.owner = THIS_MODULE,
};
......@@ -15,6 +15,7 @@
#include <asm/system.h>
#include <asm/bitops.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
......@@ -222,45 +223,40 @@ noop_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
return NET_XMIT_CN;
}
struct Qdisc_ops noop_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "noop",
.priv_size = 0,
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.requeue = noop_requeue,
struct Qdisc_ops noop_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "noop",
.priv_size = 0,
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.requeue = noop_requeue,
.owner = THIS_MODULE,
};
struct Qdisc noop_qdisc =
{
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.flags = TCQ_F_BUILTIN,
.ops = &noop_qdisc_ops,
struct Qdisc noop_qdisc = {
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.flags = TCQ_F_BUILTIN,
.ops = &noop_qdisc_ops,
};
struct Qdisc_ops noqueue_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "noqueue",
.priv_size = 0,
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.requeue = noop_requeue,
struct Qdisc_ops noqueue_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "noqueue",
.priv_size = 0,
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.requeue = noop_requeue,
.owner = THIS_MODULE,
};
struct Qdisc noqueue_qdisc =
{
.enqueue = NULL,
.dequeue = noop_dequeue,
.flags = TCQ_F_BUILTIN,
.ops = &noqueue_qdisc_ops,
struct Qdisc noqueue_qdisc = {
.enqueue = NULL,
.dequeue = noop_dequeue,
.flags = TCQ_F_BUILTIN,
.ops = &noqueue_qdisc_ops,
};
......@@ -343,19 +339,17 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt)
return 0;
}
static struct Qdisc_ops pfifo_fast_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "pfifo_fast",
.priv_size = 3 * sizeof(struct sk_buff_head),
.enqueue = pfifo_fast_enqueue,
.dequeue = pfifo_fast_dequeue,
.requeue = pfifo_fast_requeue,
.init = pfifo_fast_init,
.reset = pfifo_fast_reset,
static struct Qdisc_ops pfifo_fast_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "pfifo_fast",
.priv_size = 3 * sizeof(struct sk_buff_head),
.enqueue = pfifo_fast_enqueue,
.dequeue = pfifo_fast_dequeue,
.requeue = pfifo_fast_requeue,
.init = pfifo_fast_init,
.reset = pfifo_fast_reset,
.owner = THIS_MODULE,
};
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
......@@ -422,6 +416,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
ops->reset(qdisc);
if (ops->destroy)
ops->destroy(qdisc);
module_put(ops->owner);
if (!(qdisc->flags&TCQ_F_BUILTIN))
kfree(qdisc);
}
......
......@@ -348,7 +348,6 @@ static int gred_change(struct Qdisc *sch, struct rtattr *opt)
table->grio=sopt->grio;
table->initd=0;
/* probably need to clear all the table DP entries as well */
MOD_INC_USE_COUNT;
return 0;
}
......@@ -490,7 +489,6 @@ static int gred_init(struct Qdisc *sch, struct rtattr *opt)
table->def=sopt->def_DP;
table->grio=sopt->grio;
table->initd=0;
MOD_INC_USE_COUNT;
return 0;
}
......@@ -602,27 +600,23 @@ static void gred_destroy(struct Qdisc *sch)
if (table->tab[i])
kfree(table->tab[i]);
}
MOD_DEC_USE_COUNT;
}
struct Qdisc_ops gred_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "gred",
.priv_size = sizeof(struct gred_sched),
.enqueue = gred_enqueue,
.dequeue = gred_dequeue,
.requeue = gred_requeue,
.drop = gred_drop,
.init = gred_init,
.reset = gred_reset,
.destroy = gred_destroy,
.change = gred_change,
.dump = gred_dump,
struct Qdisc_ops gred_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "gred",
.priv_size = sizeof(struct gred_sched),
.enqueue = gred_enqueue,
.dequeue = gred_dequeue,
.requeue = gred_requeue,
.drop = gred_drop,
.init = gred_init,
.reset = gred_reset,
.destroy = gred_destroy,
.change = gred_change,
.dump = gred_dump,
.owner = THIS_MODULE,
};
......
......@@ -1167,7 +1167,6 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt)
q->rate2quantum = 1;
q->defcls = gopt->defcls;
MOD_INC_USE_COUNT;
return 0;
}
......@@ -1352,7 +1351,6 @@ static void htb_destroy(struct Qdisc* sch)
htb_destroy_filters(&q->filter_list);
__skb_queue_purge(&q->direct_queue);
MOD_DEC_USE_COUNT;
}
static int htb_delete(struct Qdisc *sch, unsigned long arg)
......@@ -1588,41 +1586,35 @@ static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg)
}
}
static struct Qdisc_class_ops htb_class_ops =
{
htb_graft,
htb_leaf,
htb_get,
htb_put,
htb_change_class,
htb_delete,
htb_walk,
htb_find_tcf,
htb_bind_filter,
htb_unbind_filter,
htb_dump_class,
static struct Qdisc_class_ops htb_class_ops = {
.graft = htb_graft,
.leaf = htb_leaf,
.get = htb_get,
.put = htb_put,
.change = htb_change_class,
.delete = htb_delete,
.walk = htb_walk,
.tcf_chain = htb_find_tcf,
.bind_tcf = htb_bind_filter,
.unbind_tcf = htb_unbind_filter,
.dump = htb_dump_class,
};
struct Qdisc_ops htb_qdisc_ops =
{
NULL,
&htb_class_ops,
"htb",
sizeof(struct htb_sched),
htb_enqueue,
htb_dequeue,
htb_requeue,
htb_drop,
htb_init,
htb_reset,
htb_destroy,
NULL /* htb_change */,
htb_dump,
struct Qdisc_ops htb_qdisc_ops = {
.next = NULL,
.cl_ops = &htb_class_ops,
.id = "htb",
.priv_size = sizeof(struct htb_sched),
.enqueue = htb_enqueue,
.dequeue = htb_dequeue,
.requeue = htb_requeue,
.drop = htb_drop,
.init = htb_init,
.reset = htb_reset,
.destroy = htb_destroy,
.change = NULL /* htb_change */,
.dump = htb_dump,
.owner = THIS_MODULE,
};
#ifdef MODULE
......
......@@ -262,7 +262,6 @@ int ingress_init(struct Qdisc *sch,struct rtattr *opt)
memset(p, 0, sizeof(*p));
p->filter_list = NULL;
p->q = &noop_qdisc;
MOD_INC_USE_COUNT;
return 0;
error:
return -EINVAL;
......@@ -308,9 +307,6 @@ static void ingress_destroy(struct Qdisc *sch)
/* for future use */
qdisc_destroy(p->q);
#endif
MOD_DEC_USE_COUNT;
}
......@@ -329,41 +325,35 @@ static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
return -1;
}
static struct Qdisc_class_ops ingress_class_ops =
{
.graft = ingress_graft,
.leaf = ingress_leaf,
.get = ingress_get,
.put = ingress_put,
.change = ingress_change,
.delete = NULL,
.walk = ingress_walk,
.tcf_chain = ingress_find_tcf,
.bind_tcf = ingress_bind_filter,
.unbind_tcf = ingress_put,
.dump = NULL,
static struct Qdisc_class_ops ingress_class_ops = {
.graft = ingress_graft,
.leaf = ingress_leaf,
.get = ingress_get,
.put = ingress_put,
.change = ingress_change,
.delete = NULL,
.walk = ingress_walk,
.tcf_chain = ingress_find_tcf,
.bind_tcf = ingress_bind_filter,
.unbind_tcf = ingress_put,
.dump = NULL,
};
struct Qdisc_ops ingress_qdisc_ops =
{
.next = NULL,
.cl_ops = &ingress_class_ops,
.id = "ingress",
.priv_size = sizeof(struct ingress_qdisc_data),
.enqueue = ingress_enqueue,
.dequeue = ingress_dequeue,
.requeue = ingress_requeue,
.drop = ingress_drop,
.init = ingress_init,
.reset = ingress_reset,
.destroy = ingress_destroy,
.change = NULL,
.dump = ingress_dump,
struct Qdisc_ops ingress_qdisc_ops = {
.next = NULL,
.cl_ops = &ingress_class_ops,
.id = "ingress",
.priv_size = sizeof(struct ingress_qdisc_data),
.enqueue = ingress_enqueue,
.dequeue = ingress_dequeue,
.requeue = ingress_requeue,
.drop = ingress_drop,
.init = ingress_init,
.reset = ingress_reset,
.destroy = ingress_destroy,
.change = NULL,
.dump = ingress_dump,
.owner = THIS_MODULE,
};
......
......@@ -169,7 +169,6 @@ prio_destroy(struct Qdisc* sch)
qdisc_destroy(q->queues[prio]);
q->queues[prio] = &noop_qdisc;
}
MOD_DEC_USE_COUNT;
}
static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
......@@ -233,7 +232,6 @@ static int prio_init(struct Qdisc *sch, struct rtattr *opt)
if ((err= prio_tune(sch, opt)) != 0)
return err;
}
MOD_INC_USE_COUNT;
return 0;
}
......@@ -369,42 +367,35 @@ static struct tcf_proto ** prio_find_tcf(struct Qdisc *sch, unsigned long cl)
return &q->filter_list;
}
static struct Qdisc_class_ops prio_class_ops =
{
.graft = prio_graft,
.leaf = prio_leaf,
.get = prio_get,
.put = prio_put,
.change = prio_change,
.delete = prio_delete,
.walk = prio_walk,
.tcf_chain = prio_find_tcf,
.bind_tcf = prio_bind,
.unbind_tcf = prio_put,
.dump = prio_dump_class,
static struct Qdisc_class_ops prio_class_ops = {
.graft = prio_graft,
.leaf = prio_leaf,
.get = prio_get,
.put = prio_put,
.change = prio_change,
.delete = prio_delete,
.walk = prio_walk,
.tcf_chain = prio_find_tcf,
.bind_tcf = prio_bind,
.unbind_tcf = prio_put,
.dump = prio_dump_class,
};
struct Qdisc_ops prio_qdisc_ops =
{
.next = NULL,
.cl_ops = &prio_class_ops,
.id = "prio",
.priv_size = sizeof(struct prio_sched_data),
.enqueue = prio_enqueue,
.dequeue = prio_dequeue,
.requeue = prio_requeue,
.drop = prio_drop,
.init = prio_init,
.reset = prio_reset,
.destroy = prio_destroy,
.change = prio_tune,
.dump = prio_dump,
struct Qdisc_ops prio_qdisc_ops = {
.next = NULL,
.cl_ops = &prio_class_ops,
.id = "prio",
.priv_size = sizeof(struct prio_sched_data),
.enqueue = prio_enqueue,
.dequeue = prio_dequeue,
.requeue = prio_requeue,
.drop = prio_drop,
.init = prio_init,
.reset = prio_reset,
.destroy = prio_destroy,
.change = prio_tune,
.dump = prio_dump,
.owner = THIS_MODULE,
};
#ifdef MODULE
......
......@@ -407,14 +407,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt)
static int red_init(struct Qdisc* sch, struct rtattr *opt)
{
int err;
MOD_INC_USE_COUNT;
if ((err = red_change(sch, opt)) != 0) {
MOD_DEC_USE_COUNT;
}
return err;
return red_change(sch, opt);
}
......@@ -458,27 +451,23 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
static void red_destroy(struct Qdisc *sch)
{
MOD_DEC_USE_COUNT;
}
struct Qdisc_ops red_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "red",
.priv_size = sizeof(struct red_sched_data),
.enqueue = red_enqueue,
.dequeue = red_dequeue,
.requeue = red_requeue,
.drop = red_drop,
.init = red_init,
.reset = red_reset,
.destroy = red_destroy,
.change = red_change,
.dump = red_dump,
struct Qdisc_ops red_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "red",
.priv_size = sizeof(struct red_sched_data),
.enqueue = red_enqueue,
.dequeue = red_dequeue,
.requeue = red_requeue,
.drop = red_drop,
.init = red_init,
.reset = red_reset,
.destroy = red_destroy,
.change = red_change,
.dump = red_dump,
.owner = THIS_MODULE,
};
......
......@@ -431,7 +431,6 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
}
for (i=0; i<SFQ_DEPTH; i++)
sfq_link(q, i);
MOD_INC_USE_COUNT;
return 0;
}
......@@ -439,7 +438,6 @@ static void sfq_destroy(struct Qdisc *sch)
{
struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
del_timer(&q->perturb_timer);
MOD_DEC_USE_COUNT;
}
static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
......@@ -464,24 +462,21 @@ static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
return -1;
}
struct Qdisc_ops sfq_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "sfq",
.priv_size = sizeof(struct sfq_sched_data),
.enqueue = sfq_enqueue,
.dequeue = sfq_dequeue,
.requeue = sfq_requeue,
.drop = sfq_drop,
.init = sfq_init,
.reset = sfq_reset,
.destroy = sfq_destroy,
.change = NULL,
.dump = sfq_dump,
struct Qdisc_ops sfq_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "sfq",
.priv_size = sizeof(struct sfq_sched_data),
.enqueue = sfq_enqueue,
.dequeue = sfq_dequeue,
.requeue = sfq_requeue,
.drop = sfq_drop,
.init = sfq_init,
.reset = sfq_reset,
.destroy = sfq_destroy,
.change = NULL,
.dump = sfq_dump,
.owner = THIS_MODULE,
};
#ifdef MODULE
......
......@@ -330,23 +330,17 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt)
static int tbf_init(struct Qdisc* sch, struct rtattr *opt)
{
int err;
struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data;
if (opt == NULL)
return -EINVAL;
MOD_INC_USE_COUNT;
PSCHED_GET_TIME(q->t_c);
init_timer(&q->wd_timer);
q->wd_timer.function = tbf_watchdog;
q->wd_timer.data = (unsigned long)sch;
if ((err = tbf_change(sch, opt)) != 0) {
MOD_DEC_USE_COUNT;
}
return err;
return tbf_change(sch, opt);
}
static void tbf_destroy(struct Qdisc *sch)
......@@ -359,8 +353,6 @@ static void tbf_destroy(struct Qdisc *sch)
qdisc_put_rtab(q->P_tab);
if (q->R_tab)
qdisc_put_rtab(q->R_tab);
MOD_DEC_USE_COUNT;
}
static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
......@@ -391,24 +383,20 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
return -1;
}
struct Qdisc_ops tbf_qdisc_ops =
{
.next = NULL,
.cl_ops = NULL,
.id = "tbf",
.priv_size = sizeof(struct tbf_sched_data),
.enqueue = tbf_enqueue,
.dequeue = tbf_dequeue,
.requeue = tbf_requeue,
.drop = tbf_drop,
.init = tbf_init,
.reset = tbf_reset,
.destroy = tbf_destroy,
.change = tbf_change,
.dump = tbf_dump,
struct Qdisc_ops tbf_qdisc_ops = {
.next = NULL,
.cl_ops = NULL,
.id = "tbf",
.priv_size = sizeof(struct tbf_sched_data),
.enqueue = tbf_enqueue,
.dequeue = tbf_dequeue,
.requeue = tbf_requeue,
.drop = tbf_drop,
.init = tbf_init,
.reset = tbf_reset,
.destroy = tbf_destroy,
.change = tbf_change,
.dump = tbf_dump,
};
......
......@@ -177,8 +177,6 @@ teql_destroy(struct Qdisc* sch)
} while ((prev = q) != master->slaves);
}
MOD_DEC_USE_COUNT;
}
static int teql_qdisc_init(struct Qdisc *sch, struct rtattr *opt)
......@@ -222,8 +220,6 @@ static int teql_qdisc_init(struct Qdisc *sch, struct rtattr *opt)
m->dev.mtu = dev->mtu;
m->dev.flags = (m->dev.flags&~FMASK)|(dev->flags&FMASK);
}
MOD_INC_USE_COUNT;
return 0;
}
......@@ -386,14 +382,12 @@ static int teql_master_open(struct net_device *dev)
m->dev.mtu = mtu;
m->dev.flags = (m->dev.flags&~FMASK) | flags;
netif_start_queue(&m->dev);
MOD_INC_USE_COUNT;
return 0;
}
static int teql_master_close(struct net_device *dev)
{
netif_stop_queue(dev);
MOD_DEC_USE_COUNT;
return 0;
}
......@@ -440,20 +434,19 @@ static int teql_master_init(struct net_device *dev)
static struct teql_master the_master = {
{
.next = NULL,
.cl_ops = NULL,
.id = "",
.priv_size = sizeof(struct teql_sched_data),
.enqueue = teql_enqueue,
.dequeue = teql_dequeue,
.requeue = teql_requeue,
.drop = NULL,
.init = teql_qdisc_init,
.reset = teql_reset,
.destroy = teql_destroy,
.dump = NULL,
.next = NULL,
.cl_ops = NULL,
.id = "",
.priv_size = sizeof(struct teql_sched_data),
.enqueue = teql_enqueue,
.dequeue = teql_dequeue,
.requeue = teql_requeue,
.drop = NULL,
.init = teql_qdisc_init,
.reset = teql_reset,
.destroy = teql_destroy,
.dump = NULL,
.owner = THIS_MODULE,
},};
......@@ -474,6 +467,7 @@ int __init teql_init(void)
memcpy(the_master.qops.id, the_master.dev.name, IFNAMSIZ);
the_master.dev.init = teql_master_init;
SET_MODULE_OWNER(&the_master.dev);
err = register_netdevice(&the_master.dev);
if (err == 0) {
err = register_qdisc(&the_master.qops);
......
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