diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/drivers/net/e100/e100_main.c 2.6.1-skb-dest/drivers/net/e100/e100_main.c --- 2.6.1/drivers/net/e100/e100_main.c 2003-12-30 08:11:09.000000000 +0200 +++ 2.6.1-skb-dest/drivers/net/e100/e100_main.c 2004-01-12 02:38:59.000000000 +0200 @@ -229,6 +229,18 @@ e100_get_rx_struct(struct e100_private * return rx_struct; } +static atomic_t destructor_counter = ATOMIC_INIT(0); + +static void e100_dest(struct sk_buff* skb) +{ + int val; + + atomic_dec(&destructor_counter); + + if ((val = atomic_read(&destructor_counter)) < 10) + printk("destructor_counter == %d\n", val); +} + /** * e100_alloc_skb - allocate an skb for the adapter * @bdp: atapter's private data struct @@ -259,6 +271,8 @@ e100_alloc_skb(struct e100_private *bdp) if (!rx_struct->dma_addr) goto err; skb_reserve(new_skb, bdp->rfd_size); + atomic_inc(&destructor_counter); + skb_add_destructor(new_skb, e100_dest); return rx_struct; } else { return NULL; diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/include/linux/skbuff.h 2.6.1-skb-dest/include/linux/skbuff.h --- 2.6.1/include/linux/skbuff.h 2004-01-10 22:39:32.000000000 +0200 +++ 2.6.1-skb-dest/include/linux/skbuff.h 2004-01-12 02:25:22.000000000 +0200 @@ -27,6 +27,7 @@ #include #include #include +#include #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ @@ -147,6 +148,10 @@ struct skb_shared_info { skb_frag_t frags[MAX_SKB_FRAGS]; }; +typedef void (*skb_destructor_t) (struct sk_buff* skb); + +#define MAX_NUM_SKB_DESTRUCTORS (2) + /** * struct sk_buff - socket buffer * @next: Next buffer in list @@ -177,7 +182,8 @@ struct skb_shared_info { * @data: Data head pointer * @tail: Tail pointer * @end: End pointer - * @destructor: Destruct function + * @numdests: The number of registered destructors + * @destructors: Destructors function array * @nfmark: Can be used for communication between hooks * @nfcache: Cache info * @nfct: Associated connection, if any @@ -241,7 +247,9 @@ struct sk_buff { unsigned short protocol, security; - void (*destructor)(struct sk_buff *skb); + skb_destructor_t destructors[MAX_NUM_SKB_DESTRUCTORS]; + size_t numdests; + #ifdef CONFIG_NETFILTER unsigned long nfmark; __u32 nfcache; @@ -995,19 +1003,54 @@ static inline int pskb_trim(struct sk_bu return (len < skb->len) ? __pskb_trim(skb, len) : 0; } +static inline void skb_init_destructors(struct sk_buff* skb) +{ + memset(skb->destructors, 0, sizeof(skb->destructors)); + skb->numdests = 0; +} + +static inline void skb_call_destructors(struct sk_buff* skb) +{ + if (skb->numdests && in_irq()) { + printk(KERN_WARNING "Warning: kfree_skb on " + "hard IRQ %p\n", NET_CALLER(skb)); + } + + while (skb->numdests--) { + skb_destructor_t dest; + size_t idx = skb->numdests; + + dest = skb->destructors[idx]; + BUG_ON(!dest); + (*dest)(skb); + + skb->destructors[idx] = NULL; + } + + skb->numdests = 0; +} + +static inline void skb_add_destructor(struct sk_buff* skb, skb_destructor_t dest) +{ + size_t idx = skb->numdests++; + + BUG_ON(idx >= MAX_NUM_SKB_DESTRUCTORS); + BUG_ON(skb->destructors[idx]); /* if it's already set */ + + skb->destructors[idx] = dest; +} + /** * skb_orphan - orphan a buffer * @skb: buffer to orphan * - * If a buffer currently has an owner then we call the owner's - * destructor function and make the @skb unowned. The buffer continues + * If a buffer has any destructors registered, we call them. Then + * we make the @skb unowned. The buffer continues * to exist but is no longer charged to its former owner. */ static inline void skb_orphan(struct sk_buff *skb) { - if (skb->destructor) - skb->destructor(skb); - skb->destructor = NULL; + skb_call_destructors(skb); skb->sk = NULL; } diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/include/net/sock.h 2.6.1-skb-dest/include/net/sock.h --- 2.6.1/include/net/sock.h 2004-01-10 22:39:34.000000000 +0200 +++ 2.6.1-skb-dest/include/net/sock.h 2004-01-12 00:29:46.000000000 +0200 @@ -888,14 +888,14 @@ static inline void skb_set_owner_w(struc { sock_hold(sk); skb->sk = sk; - skb->destructor = sock_wfree; + skb_add_destructor(skb, sock_wfree); atomic_add(skb->truesize, &sk->sk_wmem_alloc); } static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) { skb->sk = sk; - skb->destructor = sock_rfree; + skb_add_destructor(skb, sock_rfree); atomic_add(skb->truesize, &sk->sk_rmem_alloc); } diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/include/net/tcp.h 2.6.1-skb-dest/include/net/tcp.h --- 2.6.1/include/net/tcp.h 2004-01-10 22:39:34.000000000 +0200 +++ 2.6.1-skb-dest/include/net/tcp.h 2004-01-12 00:29:46.000000000 +0200 @@ -1889,7 +1889,7 @@ extern void tcp_rfree(struct sk_buff *sk static inline void tcp_set_owner_r(struct sk_buff *skb, struct sock *sk) { skb->sk = sk; - skb->destructor = tcp_rfree; + skb_add_destructor(skb, tcp_rfree); atomic_add(skb->truesize, &sk->sk_rmem_alloc); sk->sk_forward_alloc -= skb->truesize; } diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/Makefile 2.6.1-skb-dest/Makefile --- 2.6.1/Makefile 2004-01-10 22:37:40.000000000 +0200 +++ 2.6.1-skb-dest/Makefile 2004-01-14 10:20:00.000000000 +0200 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 1 -EXTRAVERSION = +EXTRAVERSION = -skb-dest # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/net/core/skbuff.c 2.6.1-skb-dest/net/core/skbuff.c --- 2.6.1/net/core/skbuff.c 2003-11-06 22:23:45.000000000 +0200 +++ 2.6.1-skb-dest/net/core/skbuff.c 2004-01-12 00:29:46.000000000 +0200 @@ -229,12 +229,9 @@ void __kfree_skb(struct sk_buff *skb) #ifdef CONFIG_XFRM secpath_put(skb->sp); #endif - if(skb->destructor) { - if (in_irq()) - printk(KERN_WARNING "Warning: kfree_skb on " - "hard IRQ %p\n", NET_CALLER(skb)); - skb->destructor(skb); - } + + skb_call_destructors(skb); + #ifdef CONFIG_NETFILTER nf_conntrack_put(skb->nfct); #ifdef CONFIG_BRIDGE_NETFILTER @@ -293,7 +290,7 @@ struct sk_buff *skb_clone(struct sk_buff C(priority); C(protocol); C(security); - n->destructor = NULL; + skb_init_destructors(n); #ifdef CONFIG_NETFILTER C(nfmark); C(nfcache); @@ -350,7 +347,7 @@ static void copy_skb_header(struct sk_bu new->local_df = old->local_df; new->pkt_type = old->pkt_type; new->stamp = old->stamp; - new->destructor = NULL; + skb_init_destructors(new); new->security = old->security; #ifdef CONFIG_NETFILTER new->nfmark = old->nfmark; diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/net/irda/af_irda.c 2.6.1-skb-dest/net/irda/af_irda.c --- 2.6.1/net/irda/af_irda.c 2004-01-10 22:39:42.000000000 +0200 +++ 2.6.1-skb-dest/net/irda/af_irda.c 2004-01-12 02:52:36.000000000 +0200 @@ -938,7 +938,7 @@ static int irda_accept(struct socket *so /* Wow ! What is that ? Jean II */ skb->sk = NULL; - skb->destructor = NULL; + skb_init_destructors(skb); kfree_skb(skb); sk->sk_ack_backlog--; diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/net/irda/ircomm/ircomm_lmp.c 2.6.1-skb-dest/net/irda/ircomm/ircomm_lmp.c --- 2.6.1/net/irda/ircomm/ircomm_lmp.c 2003-05-26 08:17:28.000000000 +0300 +++ 2.6.1-skb-dest/net/irda/ircomm/ircomm_lmp.c 2004-01-12 02:55:36.000000000 +0200 @@ -232,7 +232,7 @@ int ircomm_lmp_data_request(struct ircom /* Don't forget to refcount it - see ircomm_tty_do_softint() */ skb_get(skb); - skb->destructor = ircomm_lmp_flow_control; + skb_add_destructor(skb, ircomm_lmp_flow_control); if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) { IRDA_DEBUG(2, "%s(), asking TTY to slow down!\n", __FUNCTION__ ); diff -Naurp --exclude-from /home/muli/w/dontdiff 2.6.1/net/unix/af_unix.c 2.6.1-skb-dest/net/unix/af_unix.c --- 2.6.1/net/unix/af_unix.c 2004-01-10 22:39:44.000000000 +0200 +++ 2.6.1-skb-dest/net/unix/af_unix.c 2004-01-12 00:29:46.000000000 +0200 @@ -1142,7 +1142,6 @@ static void unix_detach_fds(struct scm_c int i; scm->fp = UNIXCB(skb).fp; - skb->destructor = sock_wfree; UNIXCB(skb).fp = NULL; for (i=scm->fp->count-1; i>=0; i--) @@ -1158,7 +1157,6 @@ static void unix_destruct_fds(struct sk_ /* Alas, it calls VFS */ /* So fscking what? fput() had been SMP-safe since the last Summer */ scm_destroy(&scm); - sock_wfree(skb); } static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) @@ -1167,7 +1165,7 @@ static void unix_attach_fds(struct scm_c for (i=scm->fp->count-1; i>=0; i--) unix_inflight(scm->fp->fp[i]); UNIXCB(skb).fp = scm->fp; - skb->destructor = unix_destruct_fds; + skb_add_destructor(skb, unix_destruct_fds); scm->fp = NULL; }