alloc_skb与dev_alloc_skb异同

来源:互联网 发布:一级建造师网络培训 编辑:程序博客网 时间:2024/04/30 08:53

(1) alloc_skb函数
<linux-2.6.28/include/linux/skbuff.h>
static inline struct sk_buff *alloc_skb(unsigned intsize,gfp_t priority)
{                     
        return__alloc_skb(size, priority, 0, -1);
}

__alloc_skb函数定义于文件<linux-2.6.28/net/core/skbuff.c>,它分配sk_buff结构及数据缓存块:(a)通过kmem_cache_alloc函数从缓存里分配sk_buff数据结构;(b)通过kmalloc分配数据缓冲区。

   skb = kmem_cache_alloc(skbuff_head_cache, gfp_mask & ~_ _GFP_DMA);
    ... ... ...
    size = SKB_DATA_ALIGN(size);  //对申请的数据区大小进行对界处理
    data = kmalloc(size + sizeof(structskb_shared_info), gfp_mask);

  alloc_skb分配出来的结构示意图

 上图中的skb_shared_info结构是为用于IP数据包分段处理而增加的;

(2) dev_alloc_skb函数
主要用于设备驱动中,并在中断上下文中使用。它包装了skb_alloc函数并且在分配空间上多分了16字节空间,由于该函数主要在中断里使用,其在分配空间要求置上原子标志位GFP_ATOMIC。
<linux-2.6.28/net/core/skbuff.c>
static inline struct sk_buff *dev_alloc_skb(unsignedint length)
{
    return _ _dev_alloc_skb(length,GFP_ATOMIC);
}
static inline struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask)
{
    struct sk_buff *skb = alloc_skb(length+ 16, gfp_mask);
    if (likely(skb))
            skb_reserve(skb, 16);
    return skb;
}

skb_reserve分配出来的结构示意图

注意:
    这里通常有个疑问就是为什么dev_alloc_skb要多分配16字节的空间呢?
   <linux-2.6.28/include/linux/skbuff.h>
    Thenetworking layer reserves some headroom in skb data (via dev_alloc_skb). Thisis used to avoid having to reallocate skb data when the header has to grow. Inthe default case, if the header has to grow 16 bytes or less we avoid thereallocation.
    由此可知当skb数据头需要增加而又长度又小于16字节时,这样就可利用skb_reserve出来的空间,避免了重新分配。

原创粉丝点击