diff options
author | Anton Blanchard <anton@samba.org> | 2006-03-31 05:27:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-31 05:27:06 -0500 |
commit | 025be81e83043f20538dcced1e12c5f8d152fbdb (patch) | |
tree | b5789ee2931739c7066f5369ce699ef4f3fa758e | |
parent | 0803dbed7a23721d091639c9e173c0389dcd524a (diff) |
[NET]: Allow skb headroom to be overridden
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>
-rw-r--r-- | include/asm-powerpc/system.h | 5 | ||||
-rw-r--r-- | include/linux/skbuff.h | 29 |
2 files changed, 29 insertions, 5 deletions
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 65f5a7b2646b..d075725bf444 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h | |||
@@ -365,8 +365,11 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, | |||
365 | * powers of 2 writes until it reaches sufficient alignment). | 365 | * powers of 2 writes until it reaches sufficient alignment). |
366 | * | 366 | * |
367 | * Based on this we disable the IP header alignment in network drivers. | 367 | * Based on this we disable the IP header alignment in network drivers. |
368 | * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining | ||
369 | * cacheline alignment of buffers. | ||
368 | */ | 370 | */ |
369 | #define NET_IP_ALIGN 0 | 371 | #define NET_IP_ALIGN 0 |
372 | #define NET_SKB_PAD L1_CACHE_BYTES | ||
370 | #endif | 373 | #endif |
371 | 374 | ||
372 | #define arch_align_stack(x) (x) | 375 | #define arch_align_stack(x) (x) |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 613b9513f8b9..c4619a428d9b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -941,6 +941,25 @@ static inline void skb_reserve(struct sk_buff *skb, int len) | |||
941 | #define NET_IP_ALIGN 2 | 941 | #define NET_IP_ALIGN 2 |
942 | #endif | 942 | #endif |
943 | 943 | ||
944 | /* | ||
945 | * The networking layer reserves some headroom in skb data (via | ||
946 | * dev_alloc_skb). This is used to avoid having to reallocate skb data when | ||
947 | * the header has to grow. In the default case, if the header has to grow | ||
948 | * 16 bytes or less we avoid the reallocation. | ||
949 | * | ||
950 | * Unfortunately this headroom changes the DMA alignment of the resulting | ||
951 | * network packet. As for NET_IP_ALIGN, this unaligned DMA is expensive | ||
952 | * on some architectures. An architecture can override this value, | ||
953 | * perhaps setting it to a cacheline in size (since that will maintain | ||
954 | * cacheline alignment of the DMA). It must be a power of 2. | ||
955 | * | ||
956 | * Various parts of the networking layer expect at least 16 bytes of | ||
957 | * headroom, you should not reduce this. | ||
958 | */ | ||
959 | #ifndef NET_SKB_PAD | ||
960 | #define NET_SKB_PAD 16 | ||
961 | #endif | ||
962 | |||
944 | extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); | 963 | extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); |
945 | 964 | ||
946 | static inline void __skb_trim(struct sk_buff *skb, unsigned int len) | 965 | static inline void __skb_trim(struct sk_buff *skb, unsigned int len) |
@@ -1030,9 +1049,9 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) | |||
1030 | static inline struct sk_buff *__dev_alloc_skb(unsigned int length, | 1049 | static inline struct sk_buff *__dev_alloc_skb(unsigned int length, |
1031 | gfp_t gfp_mask) | 1050 | gfp_t gfp_mask) |
1032 | { | 1051 | { |
1033 | struct sk_buff *skb = alloc_skb(length + 16, gfp_mask); | 1052 | struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); |
1034 | if (likely(skb)) | 1053 | if (likely(skb)) |
1035 | skb_reserve(skb, 16); | 1054 | skb_reserve(skb, NET_SKB_PAD); |
1036 | return skb; | 1055 | return skb; |
1037 | } | 1056 | } |
1038 | #else | 1057 | #else |
@@ -1070,13 +1089,15 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length) | |||
1070 | */ | 1089 | */ |
1071 | static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) | 1090 | static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) |
1072 | { | 1091 | { |
1073 | int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb); | 1092 | int delta = (headroom > NET_SKB_PAD ? headroom : NET_SKB_PAD) - |
1093 | skb_headroom(skb); | ||
1074 | 1094 | ||
1075 | if (delta < 0) | 1095 | if (delta < 0) |
1076 | delta = 0; | 1096 | delta = 0; |
1077 | 1097 | ||
1078 | if (delta || skb_cloned(skb)) | 1098 | if (delta || skb_cloned(skb)) |
1079 | return pskb_expand_head(skb, (delta + 15) & ~15, 0, GFP_ATOMIC); | 1099 | return pskb_expand_head(skb, (delta + (NET_SKB_PAD-1)) & |
1100 | ~(NET_SKB_PAD-1), 0, GFP_ATOMIC); | ||
1080 | return 0; | 1101 | return 0; |
1081 | } | 1102 | } |
1082 | 1103 | ||