Hi art,
I think maybe my first noise is more easy to go.
As you know, sk_buff is made of a skb header and the packet data
container. The skb header is allocated from the slab cache, while the
packet data container is allocated via kmalloc().
So if you can add your low 32MB memory into ZONE_DMA, then your can call
__dev_alloc_skb() with __GFP_DMA flag in your driver, which should make
sure that the packet data container is in ZONE_DMA.
Best Regards,
Mark.Zhan
art wrote:
Hello Rongkai,
Thanks! Good idea!
ZR> After having a look at the latest 2.6.17-rc6 codes, __dev_alloc_skb is defined like this:
ZR> #ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB
ZR> /**
ZR> * __dev_alloc_skb - allocate an skbuff for sending
ZR> * @length: length to allocate
ZR> * @gfp_mask: get_free_pages mask, passed to alloc_skb
ZR> *
ZR> * Allocate a new &sk_buff and assign it a usage count of one. The
ZR> * buffer has unspecified headroom built in. Users should allocate
ZR> * the headroom they think they need without accounting for the
ZR> * built in space. The built in space is used for optimisations.
ZR> *
ZR> * %NULL is returned in there is no free memory.
ZR> */
ZR> static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
ZR> gfp_t gfp_mask)
ZR> {
ZR> struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
ZR> if (likely(skb))
ZR> skb_reserve(skb, NET_SKB_PAD);
ZR> return skb;
ZR> }
ZR> #else
ZR> extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask);
ZR> #endif
ZR> Therefore, you also can consider to implement your machine-specific __dev_alloc_skb() function, and force the skb is allocated from your low 32MB memory zone.