Hi, On ppc64 we want DMA writes (ie receive packets) to be aligned, hopefully on a cacheline boundary. The NET_IP_ALIGN patch got us part of the way, so that DMAs were 16 byte aligned.
The following patch addresses the other source of misalignment. Every skb has 16 bytes of headroom reserved for various optimisations, unfortunately this means all receive packets start 16 bytes into a cacheline. By allowing this to be overridden (via the NET_SKB_PAD define), we can define the headroom to be a cacheline and maintain cacheline alignment. Signed-off-by: Anton Blanchard <[EMAIL PROTECTED]> --- Any thoughts on this? The other option was to override dev_alloc_skb, but I would prefer not to if possible. Index: gr_work/include/linux/skbuff.h =================================================================== --- gr_work.orig/include/linux/skbuff.h 2005-11-08 01:58:45.830672271 -0600 +++ gr_work/include/linux/skbuff.h 2005-11-08 02:26:19.349053315 -0600 @@ -930,6 +930,23 @@ #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 0 (if the optimisation is not seen as important), + * or to a cacheline in size (since that will maintain cacheline alignment + * of the DMA). + */ +#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) @@ -1019,9 +1036,9 @@ 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 Index: gr_work/include/asm-ppc64/system.h =================================================================== --- gr_work.orig/include/asm-ppc64/system.h 2005-11-08 01:58:45.833671796 -0600 +++ gr_work/include/asm-ppc64/system.h 2005-11-08 02:27:19.276618633 -0600 @@ -297,8 +297,11 @@ * 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 #define arch_align_stack(x) (x) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html