Skip to content

Commit

Permalink
[NET]: Allow skb headroom to be overridden
Browse files Browse the repository at this point in the history
Previously we added NET_IP_ALIGN so an architecture can override the
padding done to align headers. The next step is to allow the skb
headroom to be overridden.

We currently always reserve 16 bytes to grow into, meaning all DMAs
start 16 bytes into a cacheline. On ppc64 we really want DMA writes to
start on a cacheline boundary, so we increase that headroom to one
cacheline.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Anton Blanchard authored and David S. Miller committed Mar 31, 2006
1 parent 0803dbe commit 025be81
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
5 changes: 4 additions & 1 deletion include/asm-powerpc/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,11 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
* powers of 2 writes until it reaches sufficient alignment).
*
* Based on this we disable the IP header alignment in network drivers.
* We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining
* cacheline alignment of buffers.
*/
#define NET_IP_ALIGN 0
#define NET_IP_ALIGN 0
#define NET_SKB_PAD L1_CACHE_BYTES
#endif

#define arch_align_stack(x) (x)
Expand Down
29 changes: 25 additions & 4 deletions include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,25 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
#define NET_IP_ALIGN 2
#endif

/*
* The networking layer reserves some headroom in skb data (via
* dev_alloc_skb). This is used to avoid having to reallocate skb data when
* the header has to grow. In the default case, if the header has to grow
* 16 bytes or less we avoid the reallocation.
*
* Unfortunately this headroom changes the DMA alignment of the resulting
* network packet. As for NET_IP_ALIGN, this unaligned DMA is expensive
* on some architectures. An architecture can override this value,
* perhaps setting it to a cacheline in size (since that will maintain
* cacheline alignment of the DMA). It must be a power of 2.
*
* Various parts of the networking layer expect at least 16 bytes of
* headroom, you should not reduce this.
*/
#ifndef NET_SKB_PAD
#define NET_SKB_PAD 16
#endif

extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);

static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
Expand Down Expand Up @@ -1030,9 +1049,9 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
gfp_t gfp_mask)
{
struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);
struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
if (likely(skb))
skb_reserve(skb, 16);
skb_reserve(skb, NET_SKB_PAD);
return skb;
}
#else
Expand Down Expand Up @@ -1070,13 +1089,15 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
*/
static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
{
int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb);
int delta = (headroom > NET_SKB_PAD ? headroom : NET_SKB_PAD) -
skb_headroom(skb);

if (delta < 0)
delta = 0;

if (delta || skb_cloned(skb))
return pskb_expand_head(skb, (delta + 15) & ~15, 0, GFP_ATOMIC);
return pskb_expand_head(skb, (delta + (NET_SKB_PAD-1)) &
~(NET_SKB_PAD-1), 0, GFP_ATOMIC);
return 0;
}

Expand Down

0 comments on commit 025be81

Please sign in to comment.