|
楼主 |
发表于 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;
} |
|