dev_alloc_skb()也是一个缓冲区分配函数,它主要被设备驱动使用,通常用在中断上下文中。这是一个alloc_skb()的包装函数,它会在请求分配的大小上增加16字节的空间以优化缓冲区的读写效率,它的分配要求使用原子操作(GFP_ATOMIC),这是因为它是在中断处理函数中被调用的。
dev_alloc_skb(length) uses the function alloc_skb() to create a socket buffer.
The length of this socket buffer's packet data space is length + 16 bytes.
Subsequently, skb_reserve(skb, 16) is used to move the currently valid packet
data space 16 bytes backwards. This means that the packet has now a headroom of
16 bytes and a tailroom of length bytes.
/usr/src/linux-2.6.19/include/linux/skbuff.h static inline struct
sk_buff *dev_alloc_skb(unsigned int
length) { return __dev_alloc_skb(length, GFP_ATOMIC); }
/usr/src/linux-2.6.19/include/linux/skbuff.h static
inline struct sk_buff *__dev_alloc_skb(unsigned int
length, gfp_t gfp_mask) { struct sk_buff
*skb = alloc_skb(length + NET_SKB_PAD,
gfp_mask); if (likely(skb)) skb_reserve(skb, NET_SKB_PAD); return skb; }
/usr/src/linux-2.6.19/include/linux/skbuff.h #ifndef NET_SKB_PAD #define NET_SKB_PAD 16 #endif
dev_alloc_skb(pkt_len+2)中的2是什么用途? nuc900_ether738行:skb = dev_alloc_skb(length+2);
dev_alloc_skb(int
len) 在分配空间是 就把len+16了,作为以太网头部的空间,为什么在ne2000
和3c501中又+2? dev_alloc_skb(pkt_len+2);2
wxp95
dev_alloc_skb(pkt_len+2)中的2是什么用途?
在__dev_alloc_skb里是把len+16调用alloc_skb的,但下面是
if(likely(skb)) skb_reserve(skb,16);
return
skb; skb->;data指向的是16B后面,那16字节并不是做以太网头的,你也可以看看旁边的 注释。
在驱动里面dev_alloc_skb(pkt_len+2)是分配包的长度+2, 包括了以太网头,也说明上面那16B不是给以太网头的, +2是为了ip头的对齐,驱动里面后面有
skb_reserve(skb,2); /*Force 16 byte
alignment*/ 在skbuff.h里有个NET_IP_ALIGN有说明 首先L2的地址一共是14(6+6+2)个BYTE:
L2+L3(IP addr)+L4
按照常理L2地址是在L3后加, 所以在ALLOCSKB的时候要留14个BYTE,为了以后给L2用. 但是计算机一般是4字节对齐的, 如果留14个BYTE那么IP只能排在15个byte位子, ip头要经常访问所以这样效率似乎不好. 于是在预留2个(14+2 = 16) 正好让IP头4字节对齐
详见:http://bbs./thread-2017407-1-1.html http://blog.csdn.net/wzws45/article/details/6154005
|