diff options
| author | Jamal Hadi Salim <hadi@zynx.com> | 2004-06-20 00:18:46 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.davemloft.net> | 2004-06-20 00:18:46 -0700 |
| commit | d51d5d95df511761ed5493df34aa8c2a7e33e900 (patch) | |
| tree | ebb36117b148f5a0afd284c757311531cb2323d1 /include/net | |
| parent | 4e54c4816bfe51c145382d272b19c2ae41e9e36f (diff) | |
[NET]: Fix module refcounting of TC actions.
Diffstat (limited to 'include/net')
| -rw-r--r-- | include/net/pkt_act.h | 14 | ||||
| -rw-r--r-- | include/net/pkt_sched.h | 15 |
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; |
