summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@zynx.com>2004-06-20 00:18:46 -0700
committerDavid S. Miller <davem@nuts.davemloft.net>2004-06-20 00:18:46 -0700
commitd51d5d95df511761ed5493df34aa8c2a7e33e900 (patch)
treeebb36117b148f5a0afd284c757311531cb2323d1 /include/net
parent4e54c4816bfe51c145382d272b19c2ae41e9e36f (diff)
[NET]: Fix module refcounting of TC actions.
Diffstat (limited to 'include/net')
-rw-r--r--include/net/pkt_act.h14
-rw-r--r--include/net/pkt_sched.h15
2 files changed, 17 insertions, 12 deletions
diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h
index 390b82aea577..9f37ac40f1a0 100644
--- a/include/net/pkt_act.h
+++ b/include/net/pkt_act.h
@@ -69,20 +69,21 @@ tcf_hash_destroy(struct tcf_st *p)
BUG_TRAP(0);
}
-static inline void
+static inline int
tcf_hash_release(struct tcf_st *p, int bind )
{
+ int ret = 0;
if (p) {
if (bind) {
p->bindcnt--;
}
p->refcnt--;
- if (p->refcnt > 0)
- MOD_DEC_USE_COUNT;
if(p->bindcnt <=0 && p->refcnt <= 0) {
tcf_hash_destroy(p);
+ ret = 1;
}
}
+ return ret;
}
static __inline__ int
@@ -117,7 +118,6 @@ tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
r->rta_len = skb->tail - (u8*)r;
n_i++;
if (n_i >= TCA_ACT_MAX_PRIO) {
- printk("Jamal Dump Exceeded batch limit\n");
goto done;
}
}
@@ -148,8 +148,9 @@ tcf_del_walker(struct sk_buff *skb, struct tc_action *a)
while (p != NULL) {
s_p = p->next;
- printk("tcf_del_walker deleting ..\n");
- tcf_hash_release(p, 0);
+ if (ACT_P_DELETED == tcf_hash_release(p, 0)) {
+ module_put(a->ops->owner);
+ }
n_i++;
p = s_p;
}
@@ -250,7 +251,6 @@ tcf_hash_create(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int
p->bindcnt = 1;
}
- MOD_INC_USE_COUNT;
spin_lock_init(&p->lock);
p->stats.lock = &p->lock;
p->index = parm->index ? : tcf_hash_new_index();
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index eb6c344ddd95..f0d5fc3b66cc 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -414,6 +414,8 @@ struct tcf_police
#ifdef CONFIG_NET_CLS_ACT
+#define ACT_P_CREATED 1
+#define ACT_P_DELETED 1
#define tca_gen(name) \
struct tcf_##name *next; \
u32 index; \
@@ -442,10 +444,11 @@ struct tc_action_ops
char kind[IFNAMSIZ];
__u32 type; /* TBD to match kind */
__u32 capab; /* capabilities includes 4 bit version */
+ struct module *owner;
int (*act)(struct sk_buff **, struct tc_action *);
int (*get_stats)(struct sk_buff *, struct tc_action *);
int (*dump)(struct sk_buff *, struct tc_action *,int , int);
- void (*cleanup)(struct tc_action *, int bind);
+ int (*cleanup)(struct tc_action *, int bind);
int (*lookup)(struct tc_action *, u32 );
int (*init)(struct rtattr *,struct rtattr *,struct tc_action *, int , int );
int (*walk)(struct sk_buff *, struct netlink_callback *, int , struct tc_action *);
@@ -472,24 +475,26 @@ extern void tcf_police_destroy(struct tcf_police *p);
extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est);
extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p);
-static inline void tcf_police_release(struct tcf_police *p, int bind)
+static inline int tcf_police_release(struct tcf_police *p, int bind)
{
+ int ret = 0;
#ifdef CONFIG_NET_CLS_ACT
if (p) {
if (bind) {
p->bindcnt--;
}
p->refcnt--;
- if (p->refcnt > 0)
- MOD_DEC_USE_COUNT;
- if (p->refcnt <= 0 && !p->bindcnt)
+ if (p->refcnt <= 0 && !p->bindcnt) {
tcf_police_destroy(p);
+ ret = 1;
+ }
}
#else
if (p && --p->refcnt == 0)
tcf_police_destroy(p);
#endif
+ return ret;
}
extern struct Qdisc noop_qdisc;