Commit 86df4d2e authored by David S. Miller's avatar David S. Miller

Merge branch 'net_sched-clean-up-tc-classes-and-u32-filter'

Cong Wang says:

====================
net_sched: clean up tc classes and u32 filter

Patch 1 and patch 2 prepare for patch 3. Major changes
are in patch 3 and patch 4, details are there too.

v2: Add patch 1 and 2, group all into a patchset
    Fix a coding style issue in patch 4
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7d8697af 3cd904ec
...@@ -75,7 +75,6 @@ struct Qdisc { ...@@ -75,7 +75,6 @@ struct Qdisc {
struct hlist_node hash; struct hlist_node hash;
u32 handle; u32 handle;
u32 parent; u32 parent;
void *u32_node;
struct netdev_queue *dev_queue; struct netdev_queue *dev_queue;
...@@ -147,8 +146,7 @@ struct Qdisc_class_ops { ...@@ -147,8 +146,7 @@ struct Qdisc_class_ops {
void (*qlen_notify)(struct Qdisc *, unsigned long); void (*qlen_notify)(struct Qdisc *, unsigned long);
/* Class manipulation routines */ /* Class manipulation routines */
unsigned long (*get)(struct Qdisc *, u32 classid); unsigned long (*find)(struct Qdisc *, u32 classid);
void (*put)(struct Qdisc *, unsigned long);
int (*change)(struct Qdisc *, u32, u32, int (*change)(struct Qdisc *, u32, u32,
struct nlattr **, unsigned long *); struct nlattr **, unsigned long *);
int (*delete)(struct Qdisc *, unsigned long); int (*delete)(struct Qdisc *, unsigned long);
......
...@@ -586,7 +586,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -586,7 +586,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
/* Do we search for filter, attached to class? */ /* Do we search for filter, attached to class? */
if (TC_H_MIN(parent)) { if (TC_H_MIN(parent)) {
cl = cops->get(q, parent); cl = cops->find(q, parent);
if (cl == 0) if (cl == 0)
return -ENOENT; return -ENOENT;
} }
...@@ -716,8 +716,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -716,8 +716,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
errout: errout:
if (chain) if (chain)
tcf_chain_put(chain); tcf_chain_put(chain);
if (cl)
cops->put(q, cl);
if (err == -EAGAIN) if (err == -EAGAIN)
/* Replay the request. */ /* Replay the request. */
goto replay; goto replay;
...@@ -822,17 +820,17 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -822,17 +820,17 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
goto out; goto out;
cops = q->ops->cl_ops; cops = q->ops->cl_ops;
if (!cops) if (!cops)
goto errout; goto out;
if (!cops->tcf_block) if (!cops->tcf_block)
goto errout; goto out;
if (TC_H_MIN(tcm->tcm_parent)) { if (TC_H_MIN(tcm->tcm_parent)) {
cl = cops->get(q, tcm->tcm_parent); cl = cops->find(q, tcm->tcm_parent);
if (cl == 0) if (cl == 0)
goto errout; goto out;
} }
block = cops->tcf_block(q, cl); block = cops->tcf_block(q, cl);
if (!block) if (!block)
goto errout; goto out;
index_start = cb->args[0]; index_start = cb->args[0];
index = 0; index = 0;
...@@ -847,9 +845,6 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -847,9 +845,6 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
cb->args[0] = index; cb->args[0] = index;
errout:
if (cl)
cops->put(q, cl);
out: out:
return skb->len; return skb->len;
} }
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/netdevice.h>
#include <linux/hash.h>
#include <net/netlink.h> #include <net/netlink.h>
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
...@@ -92,6 +94,7 @@ struct tc_u_common { ...@@ -92,6 +94,7 @@ struct tc_u_common {
struct Qdisc *q; struct Qdisc *q;
int refcnt; int refcnt;
u32 hgenerator; u32 hgenerator;
struct hlist_node hnode;
struct rcu_head rcu; struct rcu_head rcu;
}; };
...@@ -323,12 +326,40 @@ static u32 gen_new_htid(struct tc_u_common *tp_c) ...@@ -323,12 +326,40 @@ static u32 gen_new_htid(struct tc_u_common *tp_c)
return i > 0 ? (tp_c->hgenerator|0x800)<<20 : 0; return i > 0 ? (tp_c->hgenerator|0x800)<<20 : 0;
} }
static struct hlist_head *tc_u_common_hash;
#define U32_HASH_SHIFT 10
#define U32_HASH_SIZE (1 << U32_HASH_SHIFT)
static unsigned int tc_u_hash(const struct tcf_proto *tp)
{
struct net_device *dev = tp->q->dev_queue->dev;
u32 qhandle = tp->q->handle;
int ifindex = dev->ifindex;
return hash_64((u64)ifindex << 32 | qhandle, U32_HASH_SHIFT);
}
static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp)
{
struct tc_u_common *tc;
unsigned int h;
h = tc_u_hash(tp);
hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) {
if (tc->q == tp->q)
return tc;
}
return NULL;
}
static int u32_init(struct tcf_proto *tp) static int u32_init(struct tcf_proto *tp)
{ {
struct tc_u_hnode *root_ht; struct tc_u_hnode *root_ht;
struct tc_u_common *tp_c; struct tc_u_common *tp_c;
unsigned int h;
tp_c = tp->q->u32_node; tp_c = tc_u_common_find(tp);
root_ht = kzalloc(sizeof(*root_ht), GFP_KERNEL); root_ht = kzalloc(sizeof(*root_ht), GFP_KERNEL);
if (root_ht == NULL) if (root_ht == NULL)
...@@ -345,7 +376,10 @@ static int u32_init(struct tcf_proto *tp) ...@@ -345,7 +376,10 @@ static int u32_init(struct tcf_proto *tp)
return -ENOBUFS; return -ENOBUFS;
} }
tp_c->q = tp->q; tp_c->q = tp->q;
tp->q->u32_node = tp_c; INIT_HLIST_NODE(&tp_c->hnode);
h = tc_u_hash(tp);
hlist_add_head(&tp_c->hnode, &tc_u_common_hash[h]);
} }
tp_c->refcnt++; tp_c->refcnt++;
...@@ -585,7 +619,7 @@ static void u32_destroy(struct tcf_proto *tp) ...@@ -585,7 +619,7 @@ static void u32_destroy(struct tcf_proto *tp)
if (--tp_c->refcnt == 0) { if (--tp_c->refcnt == 0) {
struct tc_u_hnode *ht; struct tc_u_hnode *ht;
tp->q->u32_node = NULL; hlist_del(&tp_c->hnode);
for (ht = rtnl_dereference(tp_c->hlist); for (ht = rtnl_dereference(tp_c->hlist);
ht; ht;
...@@ -1213,6 +1247,8 @@ static struct tcf_proto_ops cls_u32_ops __read_mostly = { ...@@ -1213,6 +1247,8 @@ static struct tcf_proto_ops cls_u32_ops __read_mostly = {
static int __init init_u32(void) static int __init init_u32(void)
{ {
int i, ret;
pr_info("u32 classifier\n"); pr_info("u32 classifier\n");
#ifdef CONFIG_CLS_U32_PERF #ifdef CONFIG_CLS_U32_PERF
pr_info(" Performance counters on\n"); pr_info(" Performance counters on\n");
...@@ -1223,12 +1259,25 @@ static int __init init_u32(void) ...@@ -1223,12 +1259,25 @@ static int __init init_u32(void)
#ifdef CONFIG_NET_CLS_ACT #ifdef CONFIG_NET_CLS_ACT
pr_info(" Actions configured\n"); pr_info(" Actions configured\n");
#endif #endif
return register_tcf_proto_ops(&cls_u32_ops); tc_u_common_hash = kvmalloc_array(U32_HASH_SIZE,
sizeof(struct hlist_head),
GFP_KERNEL);
if (!tc_u_common_hash)
return -ENOMEM;
for (i = 0; i < U32_HASH_SIZE; i++)
INIT_HLIST_HEAD(&tc_u_common_hash[i]);
ret = register_tcf_proto_ops(&cls_u32_ops);
if (ret)
kvfree(tc_u_common_hash);
return ret;
} }
static void __exit exit_u32(void) static void __exit exit_u32(void)
{ {
unregister_tcf_proto_ops(&cls_u32_ops); unregister_tcf_proto_ops(&cls_u32_ops);
kvfree(tc_u_common_hash);
} }
module_init(init_u32) module_init(init_u32)
......
This diff is collapsed.
...@@ -108,23 +108,29 @@ static struct Qdisc *atm_tc_leaf(struct Qdisc *sch, unsigned long cl) ...@@ -108,23 +108,29 @@ static struct Qdisc *atm_tc_leaf(struct Qdisc *sch, unsigned long cl)
return flow ? flow->q : NULL; return flow ? flow->q : NULL;
} }
static unsigned long atm_tc_get(struct Qdisc *sch, u32 classid) static unsigned long atm_tc_find(struct Qdisc *sch, u32 classid)
{ {
struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch); struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch);
struct atm_flow_data *flow; struct atm_flow_data *flow;
pr_debug("atm_tc_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid); pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid);
flow = lookup_flow(sch, classid); flow = lookup_flow(sch, classid);
if (flow) pr_debug("%s: flow %p\n", __func__, flow);
flow->ref++;
pr_debug("atm_tc_get: flow %p\n", flow);
return (unsigned long)flow; return (unsigned long)flow;
} }
static unsigned long atm_tc_bind_filter(struct Qdisc *sch, static unsigned long atm_tc_bind_filter(struct Qdisc *sch,
unsigned long parent, u32 classid) unsigned long parent, u32 classid)
{ {
return atm_tc_get(sch, classid); struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch);
struct atm_flow_data *flow;
pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid);
flow = lookup_flow(sch, classid);
if (flow)
flow->ref++;
pr_debug("%s: flow %p\n", __func__, flow);
return (unsigned long)flow;
} }
/* /*
...@@ -234,7 +240,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, ...@@ -234,7 +240,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
excess = NULL; excess = NULL;
else { else {
excess = (struct atm_flow_data *) excess = (struct atm_flow_data *)
atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS])); atm_tc_find(sch, nla_get_u32(tb[TCA_ATM_EXCESS]));
if (!excess) if (!excess)
return -ENOENT; return -ENOENT;
} }
...@@ -262,10 +268,9 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, ...@@ -262,10 +268,9 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
for (i = 1; i < 0x8000; i++) { for (i = 1; i < 0x8000; i++) {
classid = TC_H_MAKE(sch->handle, 0x8000 | i); classid = TC_H_MAKE(sch->handle, 0x8000 | i);
cl = atm_tc_get(sch, classid); cl = atm_tc_find(sch, classid);
if (!cl) if (!cl)
break; break;
atm_tc_put(sch, cl);
} }
} }
pr_debug("atm_tc_change: new id %x\n", classid); pr_debug("atm_tc_change: new id %x\n", classid);
...@@ -305,8 +310,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, ...@@ -305,8 +310,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
*arg = (unsigned long)flow; *arg = (unsigned long)flow;
return 0; return 0;
err_out: err_out:
if (excess)
atm_tc_put(sch, (unsigned long)excess);
sockfd_put(sock); sockfd_put(sock);
return error; return error;
} }
...@@ -377,7 +380,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch, ...@@ -377,7 +380,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
result = TC_ACT_OK; /* be nice to gcc */ result = TC_ACT_OK; /* be nice to gcc */
flow = NULL; flow = NULL;
if (TC_H_MAJ(skb->priority) != sch->handle || if (TC_H_MAJ(skb->priority) != sch->handle ||
!(flow = (struct atm_flow_data *)atm_tc_get(sch, skb->priority))) { !(flow = (struct atm_flow_data *)atm_tc_find(sch, skb->priority))) {
struct tcf_proto *fl; struct tcf_proto *fl;
list_for_each_entry(flow, &p->flows, list) { list_for_each_entry(flow, &p->flows, list) {
...@@ -655,8 +658,7 @@ static int atm_tc_dump(struct Qdisc *sch, struct sk_buff *skb) ...@@ -655,8 +658,7 @@ static int atm_tc_dump(struct Qdisc *sch, struct sk_buff *skb)
static const struct Qdisc_class_ops atm_class_ops = { static const struct Qdisc_class_ops atm_class_ops = {
.graft = atm_tc_graft, .graft = atm_tc_graft,
.leaf = atm_tc_leaf, .leaf = atm_tc_leaf,
.get = atm_tc_get, .find = atm_tc_find,
.put = atm_tc_put,
.change = atm_tc_change, .change = atm_tc_change,
.delete = atm_tc_delete, .delete = atm_tc_delete,
.walk = atm_tc_walk, .walk = atm_tc_walk,
......
...@@ -129,7 +129,6 @@ struct cbq_class { ...@@ -129,7 +129,6 @@ struct cbq_class {
struct tcf_proto __rcu *filter_list; struct tcf_proto __rcu *filter_list;
struct tcf_block *block; struct tcf_block *block;
int refcnt;
int filters; int filters;
struct cbq_class *defaults[TC_PRIO_MAX + 1]; struct cbq_class *defaults[TC_PRIO_MAX + 1];
...@@ -1155,7 +1154,6 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -1155,7 +1154,6 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
if (err < 0) if (err < 0)
goto put_rtab; goto put_rtab;
q->link.refcnt = 1;
q->link.sibling = &q->link; q->link.sibling = &q->link;
q->link.common.classid = sch->handle; q->link.common.classid = sch->handle;
q->link.qdisc = sch; q->link.qdisc = sch;
...@@ -1388,16 +1386,11 @@ static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg) ...@@ -1388,16 +1386,11 @@ static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg)
cbq_deactivate_class(cl); cbq_deactivate_class(cl);
} }
static unsigned long cbq_get(struct Qdisc *sch, u32 classid) static unsigned long cbq_find(struct Qdisc *sch, u32 classid)
{ {
struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_sched_data *q = qdisc_priv(sch);
struct cbq_class *cl = cbq_class_lookup(q, classid);
if (cl) { return (unsigned long)cbq_class_lookup(q, classid);
cl->refcnt++;
return (unsigned long)cl;
}
return 0;
} }
static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
...@@ -1443,25 +1436,6 @@ static void cbq_destroy(struct Qdisc *sch) ...@@ -1443,25 +1436,6 @@ static void cbq_destroy(struct Qdisc *sch)
qdisc_class_hash_destroy(&q->clhash); qdisc_class_hash_destroy(&q->clhash);
} }
static void cbq_put(struct Qdisc *sch, unsigned long arg)
{
struct cbq_class *cl = (struct cbq_class *)arg;
if (--cl->refcnt == 0) {
#ifdef CONFIG_NET_CLS_ACT
spinlock_t *root_lock = qdisc_root_sleeping_lock(sch);
struct cbq_sched_data *q = qdisc_priv(sch);
spin_lock_bh(root_lock);
if (q->rx_class == cl)
q->rx_class = NULL;
spin_unlock_bh(root_lock);
#endif
cbq_destroy_class(sch, cl);
}
}
static int static int
cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca,
unsigned long *arg) unsigned long *arg)
...@@ -1608,7 +1582,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t ...@@ -1608,7 +1582,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
cl->R_tab = rtab; cl->R_tab = rtab;
rtab = NULL; rtab = NULL;
cl->refcnt = 1;
cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
if (!cl->q) if (!cl->q)
cl->q = &noop_qdisc; cl->q = &noop_qdisc;
...@@ -1689,12 +1662,7 @@ static int cbq_delete(struct Qdisc *sch, unsigned long arg) ...@@ -1689,12 +1662,7 @@ static int cbq_delete(struct Qdisc *sch, unsigned long arg)
cbq_rmprio(q, cl); cbq_rmprio(q, cl);
sch_tree_unlock(sch); sch_tree_unlock(sch);
BUG_ON(--cl->refcnt == 0); cbq_destroy_class(sch, cl);
/*
* This shouldn't happen: we "hold" one cops->get() when called
* from tc_ctl_tclass; the destroy method is done from cops->put().
*/
return 0; return 0;
} }
...@@ -1760,8 +1728,7 @@ static const struct Qdisc_class_ops cbq_class_ops = { ...@@ -1760,8 +1728,7 @@ static const struct Qdisc_class_ops cbq_class_ops = {
.graft = cbq_graft, .graft = cbq_graft,
.leaf = cbq_leaf, .leaf = cbq_leaf,
.qlen_notify = cbq_qlen_notify, .qlen_notify = cbq_qlen_notify,
.get = cbq_get, .find = cbq_find,
.put = cbq_put,
.change = cbq_change_class, .change = cbq_change_class,
.delete = cbq_delete, .delete = cbq_delete,
.walk = cbq_walk, .walk = cbq_walk,
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
struct drr_class { struct drr_class {
struct Qdisc_class_common common; struct Qdisc_class_common common;
unsigned int refcnt;
unsigned int filter_cnt; unsigned int filter_cnt;
struct gnet_stats_basic_packed bstats; struct gnet_stats_basic_packed bstats;
...@@ -111,7 +110,6 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, ...@@ -111,7 +110,6 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (cl == NULL) if (cl == NULL)
return -ENOBUFS; return -ENOBUFS;
cl->refcnt = 1;
cl->common.classid = classid; cl->common.classid = classid;
cl->quantum = quantum; cl->quantum = quantum;
cl->qdisc = qdisc_create_dflt(sch->dev_queue, cl->qdisc = qdisc_create_dflt(sch->dev_queue,
...@@ -163,32 +161,15 @@ static int drr_delete_class(struct Qdisc *sch, unsigned long arg) ...@@ -163,32 +161,15 @@ static int drr_delete_class(struct Qdisc *sch, unsigned long arg)
drr_purge_queue(cl); drr_purge_queue(cl);
qdisc_class_hash_remove(&q->clhash, &cl->common); qdisc_class_hash_remove(&q->clhash, &cl->common);
BUG_ON(--cl->refcnt == 0);
/*
* This shouldn't happen: we "hold" one cops->get() when called
* from tc_ctl_tclass; the destroy method is done from cops->put().
*/
sch_tree_unlock(sch); sch_tree_unlock(sch);
return 0;
}
static unsigned long drr_get_class(struct Qdisc *sch, u32 classid) drr_destroy_class(sch, cl);
{ return 0;
struct drr_class *cl = drr_find_class(sch, classid);
if (cl != NULL)
cl->refcnt++;
return (unsigned long)cl;
} }
static void drr_put_class(struct Qdisc *sch, unsigned long arg) static unsigned long drr_search_class(struct Qdisc *sch, u32 classid)
{ {
struct drr_class *cl = (struct drr_class *)arg; return (unsigned long)drr_find_class(sch, classid);
if (--cl->refcnt == 0)
drr_destroy_class(sch, cl);
} }
static struct tcf_block *drr_tcf_block(struct Qdisc *sch, unsigned long cl) static struct tcf_block *drr_tcf_block(struct Qdisc *sch, unsigned long cl)
...@@ -478,8 +459,7 @@ static void drr_destroy_qdisc(struct Qdisc *sch) ...@@ -478,8 +459,7 @@ static void drr_destroy_qdisc(struct Qdisc *sch)
static const struct Qdisc_class_ops drr_class_ops = { static const struct Qdisc_class_ops drr_class_ops = {
.change = drr_change_class, .change = drr_change_class,
.delete = drr_delete_class, .delete = drr_delete_class,
.get = drr_get_class, .find = drr_search_class,
.put = drr_put_class,
.tcf_block = drr_tcf_block, .tcf_block = drr_tcf_block,
.bind_tcf = drr_bind_tcf, .bind_tcf = drr_bind_tcf,
.unbind_tcf = drr_unbind_tcf, .unbind_tcf = drr_unbind_tcf,
......
...@@ -85,21 +85,21 @@ static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -85,21 +85,21 @@ static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg)
return p->q; return p->q;
} }
static unsigned long dsmark_get(struct Qdisc *sch, u32 classid) static unsigned long dsmark_find(struct Qdisc *sch, u32 classid)
{ {
pr_debug("%s(sch %p,[qdisc %p],classid %x)\n",
__func__, sch, qdisc_priv(sch), classid);
return TC_H_MIN(classid) + 1; return TC_H_MIN(classid) + 1;
} }
static unsigned long dsmark_bind_filter(struct Qdisc *sch, static unsigned long dsmark_bind_filter(struct Qdisc *sch,
unsigned long parent, u32 classid) unsigned long parent, u32 classid)
{ {
return dsmark_get(sch, classid); pr_debug("%s(sch %p,[qdisc %p],classid %x)\n",
__func__, sch, qdisc_priv(sch), classid);
return dsmark_find(sch, classid);
} }
static void dsmark_put(struct Qdisc *sch, unsigned long cl) static void dsmark_unbind_filter(struct Qdisc *sch, unsigned long cl)
{ {
} }
...@@ -469,14 +469,13 @@ static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb) ...@@ -469,14 +469,13 @@ static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb)
static const struct Qdisc_class_ops dsmark_class_ops = { static const struct Qdisc_class_ops dsmark_class_ops = {
.graft = dsmark_graft, .graft = dsmark_graft,
.leaf = dsmark_leaf, .leaf = dsmark_leaf,
.get = dsmark_get, .find = dsmark_find,
.put = dsmark_put,
.change = dsmark_change, .change = dsmark_change,
.delete = dsmark_delete, .delete = dsmark_delete,
.walk = dsmark_walk, .walk = dsmark_walk,
.tcf_block = dsmark_tcf_block, .tcf_block = dsmark_tcf_block,
.bind_tcf = dsmark_bind_filter, .bind_tcf = dsmark_bind_filter,
.unbind_tcf = dsmark_put, .unbind_tcf = dsmark_unbind_filter,
.dump = dsmark_dump_class, .dump = dsmark_dump_class,
}; };
......
...@@ -579,7 +579,7 @@ static struct Qdisc *fq_codel_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -579,7 +579,7 @@ static struct Qdisc *fq_codel_leaf(struct Qdisc *sch, unsigned long arg)
return NULL; return NULL;
} }
static unsigned long fq_codel_get(struct Qdisc *sch, u32 classid) static unsigned long fq_codel_find(struct Qdisc *sch, u32 classid)
{ {
return 0; return 0;
} }
...@@ -592,7 +592,7 @@ static unsigned long fq_codel_bind(struct Qdisc *sch, unsigned long parent, ...@@ -592,7 +592,7 @@ static unsigned long fq_codel_bind(struct Qdisc *sch, unsigned long parent,
return 0; return 0;
} }
static void fq_codel_put(struct Qdisc *q, unsigned long cl) static void fq_codel_unbind(struct Qdisc *q, unsigned long cl)
{ {
} }
...@@ -683,11 +683,10 @@ static void fq_codel_walk(struct Qdisc *sch, struct qdisc_walker *arg) ...@@ -683,11 +683,10 @@ static void fq_codel_walk(struct Qdisc *sch, struct qdisc_walker *arg)
static const struct Qdisc_class_ops fq_codel_class_ops = { static const struct Qdisc_class_ops fq_codel_class_ops = {
.leaf = fq_codel_leaf, .leaf = fq_codel_leaf,
.get = fq_codel_get, .find = fq_codel_find,
.put = fq_codel_put,
.tcf_block = fq_codel_tcf_block, .tcf_block = fq_codel_tcf_block,
.bind_tcf = fq_codel_bind, .bind_tcf = fq_codel_bind,
.unbind_tcf = fq_codel_put, .unbind_tcf = fq_codel_unbind,
.dump = fq_codel_dump_class, .dump = fq_codel_dump_class,
.dump_stats = fq_codel_dump_class_stats, .dump_stats = fq_codel_dump_class_stats,
.walk = fq_codel_walk, .walk = fq_codel_walk,
......
...@@ -110,7 +110,6 @@ enum hfsc_class_flags { ...@@ -110,7 +110,6 @@ enum hfsc_class_flags {
struct hfsc_class { struct hfsc_class {
struct Qdisc_class_common cl_common; struct Qdisc_class_common cl_common;
unsigned int refcnt; /* usage count */
struct gnet_stats_basic_packed bstats; struct gnet_stats_basic_packed bstats;
struct gnet_stats_queue qstats; struct gnet_stats_queue qstats;
...@@ -1045,7 +1044,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, ...@@ -1045,7 +1044,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
hfsc_change_usc(cl, usc, 0); hfsc_change_usc(cl, usc, 0);
cl->cl_common.classid = classid; cl->cl_common.classid = classid;
cl->refcnt = 1;
cl->sched = q; cl->sched = q;
cl->cl_parent = parent; cl->cl_parent = parent;
cl->qdisc = qdisc_create_dflt(sch->dev_queue, cl->qdisc = qdisc_create_dflt(sch->dev_queue,
...@@ -1101,13 +1099,9 @@ hfsc_delete_class(struct Qdisc *sch, unsigned long arg) ...@@ -1101,13 +1099,9 @@ hfsc_delete_class(struct Qdisc *sch, unsigned long arg)
hfsc_purge_queue(sch, cl); hfsc_purge_queue(sch, cl);
qdisc_class_hash_remove(&q->clhash, &cl->cl_common); qdisc_class_hash_remove(&q->clhash, &cl->cl_common);
BUG_ON(--cl->refcnt == 0);
/*
* This shouldn't happen: we "hold" one cops->get() when called
* from tc_ctl_tclass; the destroy method is done from cops->put().
*/
sch_tree_unlock(sch); sch_tree_unlock(sch);
hfsc_destroy_class(sch, cl);
return 0; return 0;
} }
...@@ -1208,23 +1202,9 @@ hfsc_qlen_notify(struct Qdisc *sch, unsigned long arg) ...@@ -1208,23 +1202,9 @@ hfsc_qlen_notify(struct Qdisc *sch, unsigned long arg)
} }
static unsigned long static unsigned long
hfsc_get_class(struct Qdisc *sch, u32 classid) hfsc_search_class(struct Qdisc *sch, u32 classid)
{
struct hfsc_class *cl = hfsc_find_class(classid, sch);
if (cl != NULL)
cl->refcnt++;
return (unsigned long)cl;
}
static void
hfsc_put_class(struct Qdisc *sch, unsigned long arg)
{ {
struct hfsc_class *cl = (struct hfsc_class *)arg; return (unsigned long)hfsc_find_class(classid, sch);
if (--cl->refcnt == 0)
hfsc_destroy_class(sch, cl);
} }
static unsigned long static unsigned long
...@@ -1413,7 +1393,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) ...@@ -1413,7 +1393,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
goto err_tcf; goto err_tcf;
q->root.cl_common.classid = sch->handle; q->root.cl_common.classid = sch->handle;
q->root.refcnt = 1;
q->root.sched = q; q->root.sched = q;
q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
sch->handle); sch->handle);
...@@ -1661,8 +1640,7 @@ static const struct Qdisc_class_ops hfsc_class_ops = { ...@@ -1661,8 +1640,7 @@ static const struct Qdisc_class_ops hfsc_class_ops = {
.graft = hfsc_graft_class, .graft = hfsc_graft_class,
.leaf = hfsc_class_leaf, .leaf = hfsc_class_leaf,
.qlen_notify = hfsc_qlen_notify, .qlen_notify = hfsc_qlen_notify,
.get = hfsc_get_class, .find = hfsc_search_class,
.put = hfsc_put_class,
.bind_tcf = hfsc_bind_tcf, .bind_tcf = hfsc_bind_tcf,
.unbind_tcf = hfsc_unbind_tcf, .unbind_tcf = hfsc_unbind_tcf,
.tcf_block = hfsc_tcf_block, .tcf_block = hfsc_tcf_block,
......
...@@ -107,7 +107,6 @@ struct htb_class { ...@@ -107,7 +107,6 @@ struct htb_class {
struct tcf_proto __rcu *filter_list; /* class attached filters */ struct tcf_proto __rcu *filter_list; /* class attached filters */
struct tcf_block *block; struct tcf_block *block;
int filter_cnt; int filter_cnt;
int refcnt; /* usage count of this class */
int level; /* our level (see above) */ int level; /* our level (see above) */
unsigned int children; unsigned int children;
...@@ -193,6 +192,10 @@ static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch) ...@@ -193,6 +192,10 @@ static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch)
return container_of(clc, struct htb_class, common); return container_of(clc, struct htb_class, common);
} }
static unsigned long htb_search(struct Qdisc *sch, u32 handle)
{
return (unsigned long)htb_find(handle, sch);
}
/** /**
* htb_classify - classify a packet into class * htb_classify - classify a packet into class
* *
...@@ -1189,14 +1192,6 @@ static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg) ...@@ -1189,14 +1192,6 @@ static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg)
htb_deactivate(qdisc_priv(sch), cl); htb_deactivate(qdisc_priv(sch), cl);
} }
static unsigned long htb_get(struct Qdisc *sch, u32 classid)
{
struct htb_class *cl = htb_find(classid, sch);
if (cl)
cl->refcnt++;
return (unsigned long)cl;
}
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)
...@@ -1316,22 +1311,10 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) ...@@ -1316,22 +1311,10 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
if (last_child) if (last_child)
htb_parent_to_leaf(q, cl, new_q); htb_parent_to_leaf(q, cl, new_q);
BUG_ON(--cl->refcnt == 0);
/*
* This shouldn't happen: we "hold" one cops->get() when called
* from tc_ctl_tclass; the destroy method is done from cops->put().
*/
sch_tree_unlock(sch); sch_tree_unlock(sch);
return 0;
}
static void htb_put(struct Qdisc *sch, unsigned long arg)
{
struct htb_class *cl = (struct htb_class *)arg;
if (--cl->refcnt == 0)
htb_destroy_class(sch, cl); htb_destroy_class(sch, cl);
return 0;
} }
static int htb_change_class(struct Qdisc *sch, u32 classid, static int htb_change_class(struct Qdisc *sch, u32 classid,
...@@ -1422,7 +1405,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, ...@@ -1422,7 +1405,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
} }
} }
cl->refcnt = 1;
cl->children = 0; cl->children = 0;
INIT_LIST_HEAD(&cl->un.leaf.drop_list); INIT_LIST_HEAD(&cl->un.leaf.drop_list);
RB_CLEAR_NODE(&cl->pq_node); RB_CLEAR_NODE(&cl->pq_node);
...@@ -1598,8 +1580,7 @@ static const struct Qdisc_class_ops htb_class_ops = { ...@@ -1598,8 +1580,7 @@ static const struct Qdisc_class_ops htb_class_ops = {
.graft = htb_graft, .graft = htb_graft,
.leaf = htb_leaf, .leaf = htb_leaf,
.qlen_notify = htb_qlen_notify, .qlen_notify = htb_qlen_notify,
.get = htb_get, .find = htb_search,
.put = htb_put,
.change = htb_change_class, .change = htb_change_class,
.delete = htb_delete, .delete = htb_delete,
.walk = htb_walk, .walk = htb_walk,
......
...@@ -27,7 +27,7 @@ static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -27,7 +27,7 @@ static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg)
return NULL; return NULL;
} }
static unsigned long ingress_get(struct Qdisc *sch, u32 classid) static unsigned long ingress_find(struct Qdisc *sch, u32 classid)
{ {
return TC_H_MIN(classid) + 1; return TC_H_MIN(classid) + 1;
} }
...@@ -35,10 +35,10 @@ static unsigned long ingress_get(struct Qdisc *sch, u32 classid) ...@@ -35,10 +35,10 @@ static unsigned long ingress_get(struct Qdisc *sch, u32 classid)
static unsigned long ingress_bind_filter(struct Qdisc *sch, static unsigned long ingress_bind_filter(struct Qdisc *sch,
unsigned long parent, u32 classid) unsigned long parent, u32 classid)
{ {
return ingress_get(sch, classid); return ingress_find(sch, classid);
} }
static void ingress_put(struct Qdisc *sch, unsigned long cl) static void ingress_unbind_filter(struct Qdisc *sch, unsigned long cl)
{ {
} }
...@@ -94,12 +94,11 @@ static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) ...@@ -94,12 +94,11 @@ static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
static const struct Qdisc_class_ops ingress_class_ops = { static const struct Qdisc_class_ops ingress_class_ops = {
.leaf = ingress_leaf, .leaf = ingress_leaf,
.get = ingress_get, .find = ingress_find,
.put = ingress_put,
.walk = ingress_walk, .walk = ingress_walk,
.tcf_block = ingress_tcf_block, .tcf_block = ingress_tcf_block,
.bind_tcf = ingress_bind_filter, .bind_tcf = ingress_bind_filter,
.unbind_tcf = ingress_put, .unbind_tcf = ingress_unbind_filter,
}; };
static struct Qdisc_ops ingress_qdisc_ops __read_mostly = { static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
...@@ -117,7 +116,7 @@ struct clsact_sched_data { ...@@ -117,7 +116,7 @@ struct clsact_sched_data {
struct tcf_block *egress_block; struct tcf_block *egress_block;
}; };
static unsigned long clsact_get(struct Qdisc *sch, u32 classid) static unsigned long clsact_find(struct Qdisc *sch, u32 classid)
{ {
switch (TC_H_MIN(classid)) { switch (TC_H_MIN(classid)) {
case TC_H_MIN(TC_H_MIN_INGRESS): case TC_H_MIN(TC_H_MIN_INGRESS):
...@@ -131,7 +130,7 @@ static unsigned long clsact_get(struct Qdisc *sch, u32 classid) ...@@ -131,7 +130,7 @@ static unsigned long clsact_get(struct Qdisc *sch, u32 classid)
static unsigned long clsact_bind_filter(struct Qdisc *sch, static unsigned long clsact_bind_filter(struct Qdisc *sch,
unsigned long parent, u32 classid) unsigned long parent, u32 classid)
{ {
return clsact_get(sch, classid); return clsact_find(sch, classid);
} }
static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl) static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl)
...@@ -183,12 +182,11 @@ static void clsact_destroy(struct Qdisc *sch) ...@@ -183,12 +182,11 @@ static void clsact_destroy(struct Qdisc *sch)
static const struct Qdisc_class_ops clsact_class_ops = { static const struct Qdisc_class_ops clsact_class_ops = {
.leaf = ingress_leaf, .leaf = ingress_leaf,
.get = clsact_get, .find = clsact_find,
.put = ingress_put,
.walk = ingress_walk, .walk = ingress_walk,
.tcf_block = clsact_tcf_block, .tcf_block = clsact_tcf_block,
.bind_tcf = clsact_bind_filter, .bind_tcf = clsact_bind_filter,
.unbind_tcf = ingress_put, .unbind_tcf = ingress_unbind_filter,
}; };
static struct Qdisc_ops clsact_qdisc_ops __read_mostly = { static struct Qdisc_ops clsact_qdisc_ops __read_mostly = {
......
...@@ -165,7 +165,7 @@ static struct Qdisc *mq_leaf(struct Qdisc *sch, unsigned long cl) ...@@ -165,7 +165,7 @@ static struct Qdisc *mq_leaf(struct Qdisc *sch, unsigned long cl)
return dev_queue->qdisc_sleeping; return dev_queue->qdisc_sleeping;
} }
static unsigned long mq_get(struct Qdisc *sch, u32 classid) static unsigned long mq_find(struct Qdisc *sch, u32 classid)
{ {
unsigned int ntx = TC_H_MIN(classid); unsigned int ntx = TC_H_MIN(classid);
...@@ -174,10 +174,6 @@ static unsigned long mq_get(struct Qdisc *sch, u32 classid) ...@@ -174,10 +174,6 @@ static unsigned long mq_get(struct Qdisc *sch, u32 classid)
return ntx; return ntx;
} }
static void mq_put(struct Qdisc *sch, unsigned long cl)
{
}
static int mq_dump_class(struct Qdisc *sch, unsigned long cl, static int mq_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm) struct sk_buff *skb, struct tcmsg *tcm)
{ {
...@@ -223,8 +219,7 @@ static const struct Qdisc_class_ops mq_class_ops = { ...@@ -223,8 +219,7 @@ static const struct Qdisc_class_ops mq_class_ops = {
.select_queue = mq_select_queue, .select_queue = mq_select_queue,
.graft = mq_graft, .graft = mq_graft,
.leaf = mq_leaf, .leaf = mq_leaf,
.get = mq_get, .find = mq_find,
.put = mq_put,
.walk = mq_walk, .walk = mq_walk,
.dump = mq_dump_class, .dump = mq_dump_class,
.dump_stats = mq_dump_class_stats, .dump_stats = mq_dump_class_stats,
......
...@@ -277,7 +277,7 @@ static struct Qdisc *mqprio_leaf(struct Qdisc *sch, unsigned long cl) ...@@ -277,7 +277,7 @@ static struct Qdisc *mqprio_leaf(struct Qdisc *sch, unsigned long cl)
return dev_queue->qdisc_sleeping; return dev_queue->qdisc_sleeping;
} }
static unsigned long mqprio_get(struct Qdisc *sch, u32 classid) static unsigned long mqprio_find(struct Qdisc *sch, u32 classid)
{ {
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
unsigned int ntx = TC_H_MIN(classid); unsigned int ntx = TC_H_MIN(classid);
...@@ -287,10 +287,6 @@ static unsigned long mqprio_get(struct Qdisc *sch, u32 classid) ...@@ -287,10 +287,6 @@ static unsigned long mqprio_get(struct Qdisc *sch, u32 classid)
return ntx; return ntx;
} }
static void mqprio_put(struct Qdisc *sch, unsigned long cl)
{
}
static int mqprio_dump_class(struct Qdisc *sch, unsigned long cl, static int mqprio_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm) struct sk_buff *skb, struct tcmsg *tcm)
{ {
...@@ -403,8 +399,7 @@ static void mqprio_walk(struct Qdisc *sch, struct qdisc_walker *arg) ...@@ -403,8 +399,7 @@ static void mqprio_walk(struct Qdisc *sch, struct qdisc_walker *arg)
static const struct Qdisc_class_ops mqprio_class_ops = { static const struct Qdisc_class_ops mqprio_class_ops = {
.graft = mqprio_graft, .graft = mqprio_graft,
.leaf = mqprio_leaf, .leaf = mqprio_leaf,
.get = mqprio_get, .find = mqprio_find,
.put = mqprio_put,
.walk = mqprio_walk, .walk = mqprio_walk,
.dump = mqprio_dump_class, .dump = mqprio_dump_class,
.dump_stats = mqprio_dump_class_stats, .dump_stats = mqprio_dump_class_stats,
......
...@@ -306,7 +306,7 @@ multiq_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -306,7 +306,7 @@ multiq_leaf(struct Qdisc *sch, unsigned long arg)
return q->queues[band]; return q->queues[band];
} }
static unsigned long multiq_get(struct Qdisc *sch, u32 classid) static unsigned long multiq_find(struct Qdisc *sch, u32 classid)
{ {
struct multiq_sched_data *q = qdisc_priv(sch); struct multiq_sched_data *q = qdisc_priv(sch);
unsigned long band = TC_H_MIN(classid); unsigned long band = TC_H_MIN(classid);
...@@ -319,11 +319,11 @@ static unsigned long multiq_get(struct Qdisc *sch, u32 classid) ...@@ -319,11 +319,11 @@ static unsigned long multiq_get(struct Qdisc *sch, u32 classid)
static unsigned long multiq_bind(struct Qdisc *sch, unsigned long parent, static unsigned long multiq_bind(struct Qdisc *sch, unsigned long parent,
u32 classid) u32 classid)
{ {
return multiq_get(sch, classid); return multiq_find(sch, classid);
} }
static void multiq_put(struct Qdisc *q, unsigned long cl) static void multiq_unbind(struct Qdisc *q, unsigned long cl)
{ {
} }
...@@ -385,12 +385,11 @@ static struct tcf_block *multiq_tcf_block(struct Qdisc *sch, unsigned long cl) ...@@ -385,12 +385,11 @@ static struct tcf_block *multiq_tcf_block(struct Qdisc *sch, unsigned long cl)
static const struct Qdisc_class_ops multiq_class_ops = { static const struct Qdisc_class_ops multiq_class_ops = {
.graft = multiq_graft, .graft = multiq_graft,
.leaf = multiq_leaf, .leaf = multiq_leaf,
.get = multiq_get, .find = multiq_find,
.put = multiq_put,
.walk = multiq_walk, .walk = multiq_walk,
.tcf_block = multiq_tcf_block, .tcf_block = multiq_tcf_block,
.bind_tcf = multiq_bind, .bind_tcf = multiq_bind,
.unbind_tcf = multiq_put, .unbind_tcf = multiq_unbind,
.dump = multiq_dump_class, .dump = multiq_dump_class,
.dump_stats = multiq_dump_class_stats, .dump_stats = multiq_dump_class_stats,
}; };
......
...@@ -1096,15 +1096,11 @@ static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -1096,15 +1096,11 @@ static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg)
return q->qdisc; return q->qdisc;
} }
static unsigned long netem_get(struct Qdisc *sch, u32 classid) static unsigned long netem_find(struct Qdisc *sch, u32 classid)
{ {
return 1; return 1;
} }
static void netem_put(struct Qdisc *sch, unsigned long arg)
{
}
static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker) static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{ {
if (!walker->stop) { if (!walker->stop) {
...@@ -1120,8 +1116,7 @@ static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker) ...@@ -1120,8 +1116,7 @@ static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker)
static const struct Qdisc_class_ops netem_class_ops = { static const struct Qdisc_class_ops netem_class_ops = {
.graft = netem_graft, .graft = netem_graft,
.leaf = netem_leaf, .leaf = netem_leaf,
.get = netem_get, .find = netem_find,
.put = netem_put,
.walk = netem_walk, .walk = netem_walk,
.dump = netem_dump_class, .dump = netem_dump_class,
}; };
......
...@@ -260,7 +260,7 @@ prio_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -260,7 +260,7 @@ prio_leaf(struct Qdisc *sch, unsigned long arg)
return q->queues[band]; return q->queues[band];
} }
static unsigned long prio_get(struct Qdisc *sch, u32 classid) static unsigned long prio_find(struct Qdisc *sch, u32 classid)
{ {
struct prio_sched_data *q = qdisc_priv(sch); struct prio_sched_data *q = qdisc_priv(sch);
unsigned long band = TC_H_MIN(classid); unsigned long band = TC_H_MIN(classid);
...@@ -272,11 +272,11 @@ static unsigned long prio_get(struct Qdisc *sch, u32 classid) ...@@ -272,11 +272,11 @@ static unsigned long prio_get(struct Qdisc *sch, u32 classid)
static unsigned long prio_bind(struct Qdisc *sch, unsigned long parent, u32 classid) static unsigned long prio_bind(struct Qdisc *sch, unsigned long parent, u32 classid)
{ {
return prio_get(sch, classid); return prio_find(sch, classid);
} }
static void prio_put(struct Qdisc *q, unsigned long cl) static void prio_unbind(struct Qdisc *q, unsigned long cl)
{ {
} }
...@@ -338,12 +338,11 @@ static struct tcf_block *prio_tcf_block(struct Qdisc *sch, unsigned long cl) ...@@ -338,12 +338,11 @@ static struct tcf_block *prio_tcf_block(struct Qdisc *sch, unsigned long cl)
static const struct Qdisc_class_ops prio_class_ops = { static const struct Qdisc_class_ops prio_class_ops = {
.graft = prio_graft, .graft = prio_graft,
.leaf = prio_leaf, .leaf = prio_leaf,
.get = prio_get, .find = prio_find,
.put = prio_put,
.walk = prio_walk, .walk = prio_walk,
.tcf_block = prio_tcf_block, .tcf_block = prio_tcf_block,
.bind_tcf = prio_bind, .bind_tcf = prio_bind,
.unbind_tcf = prio_put, .unbind_tcf = prio_unbind,
.dump = prio_dump_class, .dump = prio_dump_class,
.dump_stats = prio_dump_class_stats, .dump_stats = prio_dump_class_stats,
}; };
......
...@@ -132,7 +132,6 @@ struct qfq_aggregate; ...@@ -132,7 +132,6 @@ struct qfq_aggregate;
struct qfq_class { struct qfq_class {
struct Qdisc_class_common common; struct Qdisc_class_common common;
unsigned int refcnt;
unsigned int filter_cnt; unsigned int filter_cnt;
struct gnet_stats_basic_packed bstats; struct gnet_stats_basic_packed bstats;
...@@ -477,7 +476,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, ...@@ -477,7 +476,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (cl == NULL) if (cl == NULL)
return -ENOBUFS; return -ENOBUFS;
cl->refcnt = 1;
cl->common.classid = classid; cl->common.classid = classid;
cl->deficit = lmax; cl->deficit = lmax;
...@@ -555,32 +553,15 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg) ...@@ -555,32 +553,15 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg)
qfq_purge_queue(cl); qfq_purge_queue(cl);
qdisc_class_hash_remove(&q->clhash, &cl->common); qdisc_class_hash_remove(&q->clhash, &cl->common);
BUG_ON(--cl->refcnt == 0);
/*
* This shouldn't happen: we "hold" one cops->get() when called
* from tc_ctl_tclass; the destroy method is done from cops->put().
*/
sch_tree_unlock(sch); sch_tree_unlock(sch);
return 0;
}
static unsigned long qfq_get_class(struct Qdisc *sch, u32 classid)
{
struct qfq_class *cl = qfq_find_class(sch, classid);
if (cl != NULL) qfq_destroy_class(sch, cl);
cl->refcnt++; return 0;
return (unsigned long)cl;
} }
static void qfq_put_class(struct Qdisc *sch, unsigned long arg) static unsigned long qfq_search_class(struct Qdisc *sch, u32 classid)
{ {
struct qfq_class *cl = (struct qfq_class *)arg; return (unsigned long)qfq_find_class(sch, classid);
if (--cl->refcnt == 0)
qfq_destroy_class(sch, cl);
} }
static struct tcf_block *qfq_tcf_block(struct Qdisc *sch, unsigned long cl) static struct tcf_block *qfq_tcf_block(struct Qdisc *sch, unsigned long cl)
...@@ -1510,8 +1491,7 @@ static void qfq_destroy_qdisc(struct Qdisc *sch) ...@@ -1510,8 +1491,7 @@ static void qfq_destroy_qdisc(struct Qdisc *sch)
static const struct Qdisc_class_ops qfq_class_ops = { static const struct Qdisc_class_ops qfq_class_ops = {
.change = qfq_change_class, .change = qfq_change_class,
.delete = qfq_delete_class, .delete = qfq_delete_class,
.get = qfq_get_class, .find = qfq_search_class,
.put = qfq_put_class,
.tcf_block = qfq_tcf_block, .tcf_block = qfq_tcf_block,
.bind_tcf = qfq_bind_tcf, .bind_tcf = qfq_bind_tcf,
.unbind_tcf = qfq_unbind_tcf, .unbind_tcf = qfq_unbind_tcf,
......
...@@ -311,15 +311,11 @@ static struct Qdisc *red_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -311,15 +311,11 @@ static struct Qdisc *red_leaf(struct Qdisc *sch, unsigned long arg)
return q->qdisc; return q->qdisc;
} }
static unsigned long red_get(struct Qdisc *sch, u32 classid) static unsigned long red_find(struct Qdisc *sch, u32 classid)
{ {
return 1; return 1;
} }
static void red_put(struct Qdisc *sch, unsigned long arg)
{
}
static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker) static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{ {
if (!walker->stop) { if (!walker->stop) {
...@@ -335,8 +331,7 @@ static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker) ...@@ -335,8 +331,7 @@ static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker)
static const struct Qdisc_class_ops red_class_ops = { static const struct Qdisc_class_ops red_class_ops = {
.graft = red_graft, .graft = red_graft,
.leaf = red_leaf, .leaf = red_leaf,
.get = red_get, .find = red_find,
.put = red_put,
.walk = red_walk, .walk = red_walk,
.dump = red_dump_class, .dump = red_dump_class,
}; };
......
...@@ -632,12 +632,12 @@ static struct Qdisc *sfb_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -632,12 +632,12 @@ static struct Qdisc *sfb_leaf(struct Qdisc *sch, unsigned long arg)
return q->qdisc; return q->qdisc;
} }
static unsigned long sfb_get(struct Qdisc *sch, u32 classid) static unsigned long sfb_find(struct Qdisc *sch, u32 classid)
{ {
return 1; return 1;
} }
static void sfb_put(struct Qdisc *sch, unsigned long arg) static void sfb_unbind(struct Qdisc *sch, unsigned long arg)
{ {
} }
...@@ -683,14 +683,13 @@ static unsigned long sfb_bind(struct Qdisc *sch, unsigned long parent, ...@@ -683,14 +683,13 @@ static unsigned long sfb_bind(struct Qdisc *sch, unsigned long parent,
static const struct Qdisc_class_ops sfb_class_ops = { static const struct Qdisc_class_ops sfb_class_ops = {
.graft = sfb_graft, .graft = sfb_graft,
.leaf = sfb_leaf, .leaf = sfb_leaf,
.get = sfb_get, .find = sfb_find,
.put = sfb_put,
.change = sfb_change_class, .change = sfb_change_class,
.delete = sfb_delete, .delete = sfb_delete,
.walk = sfb_walk, .walk = sfb_walk,
.tcf_block = sfb_tcf_block, .tcf_block = sfb_tcf_block,
.bind_tcf = sfb_bind, .bind_tcf = sfb_bind,
.unbind_tcf = sfb_put, .unbind_tcf = sfb_unbind,
.dump = sfb_dump_class, .dump = sfb_dump_class,
}; };
......
...@@ -808,7 +808,7 @@ static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -808,7 +808,7 @@ static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg)
return NULL; return NULL;
} }
static unsigned long sfq_get(struct Qdisc *sch, u32 classid) static unsigned long sfq_find(struct Qdisc *sch, u32 classid)
{ {
return 0; return 0;
} }
...@@ -821,7 +821,7 @@ static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent, ...@@ -821,7 +821,7 @@ static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
return 0; return 0;
} }
static void sfq_put(struct Qdisc *q, unsigned long cl) static void sfq_unbind(struct Qdisc *q, unsigned long cl)
{ {
} }
...@@ -885,11 +885,10 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) ...@@ -885,11 +885,10 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
static const struct Qdisc_class_ops sfq_class_ops = { static const struct Qdisc_class_ops sfq_class_ops = {
.leaf = sfq_leaf, .leaf = sfq_leaf,
.get = sfq_get, .find = sfq_find,
.put = sfq_put,
.tcf_block = sfq_tcf_block, .tcf_block = sfq_tcf_block,
.bind_tcf = sfq_bind, .bind_tcf = sfq_bind,
.unbind_tcf = sfq_put, .unbind_tcf = sfq_unbind,
.dump = sfq_dump_class, .dump = sfq_dump_class,
.dump_stats = sfq_dump_class_stats, .dump_stats = sfq_dump_class_stats,
.walk = sfq_walk, .walk = sfq_walk,
......
...@@ -510,15 +510,11 @@ static struct Qdisc *tbf_leaf(struct Qdisc *sch, unsigned long arg) ...@@ -510,15 +510,11 @@ static struct Qdisc *tbf_leaf(struct Qdisc *sch, unsigned long arg)
return q->qdisc; return q->qdisc;
} }
static unsigned long tbf_get(struct Qdisc *sch, u32 classid) static unsigned long tbf_find(struct Qdisc *sch, u32 classid)
{ {
return 1; return 1;
} }
static void tbf_put(struct Qdisc *sch, unsigned long arg)
{
}
static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker) static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{ {
if (!walker->stop) { if (!walker->stop) {
...@@ -534,8 +530,7 @@ static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker) ...@@ -534,8 +530,7 @@ static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker)
static const struct Qdisc_class_ops tbf_class_ops = { static const struct Qdisc_class_ops tbf_class_ops = {
.graft = tbf_graft, .graft = tbf_graft,
.leaf = tbf_leaf, .leaf = tbf_leaf,
.get = tbf_get, .find = tbf_find,
.put = tbf_put,
.walk = tbf_walk, .walk = tbf_walk,
.dump = tbf_dump_class, .dump = tbf_dump_class,
}; };
......
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