__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);
__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;
}
人气不行嘛!
不会是觉得这个问题太弱,大侠们不屑吧?:-(memset(skb, 0, offsetof(struct sk_buff, truesize));
原来对这条语句的理解有误,其真正的操作是将SKB结构中truesize变量前的所有成员清0。
只是为什么要清0呢? 从SLAB的角度出发的话应该尽量不清0啊,否则就没有必要用SLAB分配对象了吧?
页:
[1]