Commit e913173f authored by David S. Miller's avatar David S. Miller

[NET]: Make SKB layout/initialization/copy more cache friendly.

parent acacb960
...@@ -231,15 +231,8 @@ struct sk_buff { ...@@ -231,15 +231,8 @@ struct sk_buff {
pkt_type, pkt_type,
ip_summed; ip_summed;
__u32 priority; __u32 priority;
atomic_t users;
unsigned short protocol, unsigned short protocol,
security; security;
unsigned int truesize;
unsigned char *head,
*data,
*tail,
*end;
void (*destructor)(struct sk_buff *skb); void (*destructor)(struct sk_buff *skb);
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
...@@ -261,6 +254,14 @@ struct sk_buff { ...@@ -261,6 +254,14 @@ struct sk_buff {
#ifdef CONFIG_NET_SCHED #ifdef CONFIG_NET_SCHED
__u32 tc_index; /* traffic control index */ __u32 tc_index; /* traffic control index */
#endif #endif
/* These elements must be at the end, see alloc_skb() for details. */
unsigned int truesize;
atomic_t users;
unsigned char *head,
*data,
*tail,
*end;
}; };
#define SK_WMEM_MAX 65535 #define SK_WMEM_MAX 65535
......
...@@ -195,46 +195,14 @@ struct sk_buff *alloc_skb(unsigned int size, int gfp_mask) ...@@ -195,46 +195,14 @@ struct sk_buff *alloc_skb(unsigned int size, int gfp_mask)
if (!data) if (!data)
goto nodata; goto nodata;
/* XXX: does not include slab overhead */ memset(skb, 0, offsetof(struct sk_buff, truesize));
skb->next = skb->prev = NULL;
skb->list = NULL;
skb->sk = NULL;
skb->stamp.tv_sec = 0; /* No idea about time */
skb->dev = NULL;
skb->dst = NULL;
skb->sp = NULL;
memset(skb->cb, 0, sizeof(skb->cb));
/* Set up other state */
skb->len = 0;
skb->data_len = 0;
skb->csum = 0;
skb->local_df = 0;
skb->cloned = 0;
skb->pkt_type = PACKET_HOST; /* Default type */
skb->ip_summed = 0;
skb->priority = 0;
atomic_set(&skb->users, 1);
skb->security = 0; /* By default packets are insecure */
skb->truesize = size + sizeof(struct sk_buff); skb->truesize = size + sizeof(struct sk_buff);
atomic_set(&skb->users, 1);
/* Load the data pointers. */ skb->head = data;
skb->head = skb->data = skb->tail = data; skb->data = data;
skb->tail = data;
skb->end = data + size; skb->end = data + size;
skb->destructor = NULL;
#ifdef CONFIG_NETFILTER
skb->nfmark = skb->nfcache = 0;
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
skb->nf_bridge = NULL;
#endif
#endif
#ifdef CONFIG_NET_SCHED
skb->tc_index = 0;
#endif
atomic_set(&(skb_shinfo(skb)->dataref), 1); atomic_set(&(skb_shinfo(skb)->dataref), 1);
skb_shinfo(skb)->nr_frags = 0; skb_shinfo(skb)->nr_frags = 0;
skb_shinfo(skb)->tso_size = 0; skb_shinfo(skb)->tso_size = 0;
...@@ -367,10 +335,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) ...@@ -367,10 +335,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
C(nh); C(nh);
C(mac); C(mac);
C(dst); C(dst);
dst_clone(n->dst); dst_clone(skb->dst);
C(sp); C(sp);
#ifdef CONFIG_INET #ifdef CONFIG_INET
secpath_get(n->sp); secpath_get(skb->sp);
#endif #endif
memcpy(n->cb, skb->cb, sizeof(skb->cb)); memcpy(n->cb, skb->cb, sizeof(skb->cb));
C(len); C(len);
...@@ -381,24 +349,20 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) ...@@ -381,24 +349,20 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
C(pkt_type); C(pkt_type);
C(ip_summed); C(ip_summed);
C(priority); C(priority);
atomic_set(&n->users, 1);
C(protocol); C(protocol);
C(security); C(security);
C(truesize);
C(head);
C(data);
C(tail);
C(end);
n->destructor = NULL; n->destructor = NULL;
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
C(nfmark); C(nfmark);
C(nfcache); C(nfcache);
C(nfct); C(nfct);
nf_conntrack_get(skb->nfct);
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
C(nf_debug); C(nf_debug);
#endif #endif
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
C(nf_bridge); C(nf_bridge);
nf_bridge_get(skb->nf_bridge);
#endif #endif
#endif /*CONFIG_NETFILTER*/ #endif /*CONFIG_NETFILTER*/
#if defined(CONFIG_HIPPI) #if defined(CONFIG_HIPPI)
...@@ -407,15 +371,16 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) ...@@ -407,15 +371,16 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
#ifdef CONFIG_NET_SCHED #ifdef CONFIG_NET_SCHED
C(tc_index); C(tc_index);
#endif #endif
C(truesize);
atomic_set(&n->users, 1);
C(head);
C(data);
C(tail);
C(end);
atomic_inc(&(skb_shinfo(skb)->dataref)); atomic_inc(&(skb_shinfo(skb)->dataref));
skb->cloned = 1; skb->cloned = 1;
#ifdef CONFIG_NETFILTER
nf_conntrack_get(skb->nfct);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
nf_bridge_get(skb->nf_bridge);
#endif
#endif
return n; return n;
} }
...@@ -439,7 +404,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) ...@@ -439,7 +404,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->nh.raw = old->nh.raw + offset; new->nh.raw = old->nh.raw + offset;
new->mac.raw = old->mac.raw + offset; new->mac.raw = old->mac.raw + offset;
memcpy(new->cb, old->cb, sizeof(old->cb)); memcpy(new->cb, old->cb, sizeof(old->cb));
atomic_set(&new->users, 1);
new->local_df = old->local_df; new->local_df = old->local_df;
new->pkt_type = old->pkt_type; new->pkt_type = old->pkt_type;
new->stamp = old->stamp; new->stamp = old->stamp;
...@@ -449,18 +413,19 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) ...@@ -449,18 +413,19 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->nfmark = old->nfmark; new->nfmark = old->nfmark;
new->nfcache = old->nfcache; new->nfcache = old->nfcache;
new->nfct = old->nfct; new->nfct = old->nfct;
nf_conntrack_get(new->nfct); nf_conntrack_get(old->nfct);
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
new->nf_debug = old->nf_debug; new->nf_debug = old->nf_debug;
#endif #endif
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
new->nf_bridge = old->nf_bridge; new->nf_bridge = old->nf_bridge;
nf_bridge_get(new->nf_bridge); nf_bridge_get(old->nf_bridge);
#endif #endif
#endif #endif
#ifdef CONFIG_NET_SCHED #ifdef CONFIG_NET_SCHED
new->tc_index = old->tc_index; new->tc_index = old->tc_index;
#endif #endif
atomic_set(&new->users, 1);
} }
/** /**
......
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