laison 发表于 2008-12-24 14:19:11

__alloc_skb中的一个疑问

在__alloc_skb中,在申请了SKB对象和数据区后:
memset(skb, 0, offsetof(struct sk_buff, truesize));
这条语句看起来是将skb进行清0操作,根据下面的语句,truesize是整个SKB结构大小加上数据区大小。而我们知道申请数据区和SKB是两个操作,其地址空间会是连续的吗?
之所以用SLAB分配SKB,目的不就是为了减少对SKB的初始化时间吗?怎么还进行清0操作呢?
skb->truesize = size + sizeof(struct sk_buff);

laison 发表于 2008-12-24 14:19:51

__alloc_skb源码

struct sk_buff *PMC_FAST __alloc_skb(unsigned int size, gfp_t gfp_mask, int fclone, int node)
{
        struct kmem_cache *cache;
        struct skb_shared_info *shinfo;
        struct sk_buff *skb;
        u8 *data;

        如果是用于克隆的SKB,则从skbuff_fclone_cache缓冲区中申请。
        cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;

        /* Get the HEAD */
        其实就是调用kmem_cache_alloc分配一个对象,node变量没有用。
        skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
        if (!skb)
                goto out;

        /* Get the DATA. Size must match skb_add_mtu().*/
        size = SKB_DATA_ALIGN(size); 32字节对齐
       
        申请数据区的内存,注意其大小还要加上skb_shared_info结构的大小。
        data = kmalloc_node_track_caller(size + sizeof(struct         skb_shared_info),gfp_mask, node);
        if (!data)
                goto nodata;
       
        memset(skb, 0, offsetof(struct sk_buff, truesize));
        skb->truesize = size + sizeof(struct sk_buff);
        atomic_set(&skb->users, 1);
        skb->head = data;
        skb->data = data;
        skb->tail = data;
        skb->end= data + size;
        /* make sure we initialize shinfo sequentially */
        shinfo = skb_shinfo(skb);
        atomic_set(&shinfo->dataref, 1);
        shinfo->nr_frags= 0;
        shinfo->gso_size = 0;
        shinfo->gso_segs = 0;
        shinfo->gso_type = 0;
        shinfo->ip6_frag_id = 0;
        shinfo->frag_list = NULL;

        if (fclone) {
                struct sk_buff *child = skb + 1;
                atomic_t *fclone_ref = (atomic_t *) (child + 1);

                skb->fclone = SKB_FCLONE_ORIG;
                atomic_set(fclone_ref, 1);

                child->fclone = SKB_FCLONE_UNAVAILABLE;
        }
out:
        return skb;
nodata:
        kmem_cache_free(cache, skb);
        skb = NULL;
        goto out;
}

laison 发表于 2008-12-25 17:20:42

人气不行嘛!

不会是觉得这个问题太弱,大侠们不屑吧?:-(
memset(skb, 0, offsetof(struct sk_buff, truesize));
原来对这条语句的理解有误,其真正的操作是将SKB结构中truesize变量前的所有成员清0。

只是为什么要清0呢? 从SLAB的角度出发的话应该尽量不清0啊,否则就没有必要用SLAB分配对象了吧?
页: [1]
查看完整版本: __alloc_skb中的一个疑问