Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329522
  • 博文数量: 34
  • 博客积分: 860
  • 博客等级: 准尉
  • 技术积分: 524
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-23 12:04
文章存档

2011年(16)

2010年(7)

2009年(4)

2008年(7)

分类: LINUX

2011-02-28 21:58:28

  1. /*     Allocate a new skbuff. We do this ourselves so we can fill in a few
  2.  *    'private' fields and also do memory statistics to find all the
  3.  *    [BEEP] leaks.
  4.  *
  5.  */

  6. /**
  7.  *    __alloc_skb    -    allocate a network buffer
  8.  *    @size: size to allocate
  9.  *    @gfp_mask: allocation mask
  10.  *    @fclone: allocate from fclone cache instead of head cache
  11.  *        and allocate a cloned (child) skb
  12.  *    @node: numa node to allocate memory on
  13.  *
  14.  *    Allocate a new &sk_buff. The returned buffer has no headroom and a
  15.  *    tail room of size bytes. The object has a reference count of one.
  16.  *    The return is the buffer. On a failure the return is %NULL.
  17.  *
  18.  *    Buffers may only be allocated from interrupts using a @gfp_mask of
  19.  *    %GFP_ATOMIC.
  20.  */
  21. struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
  22.              int fclone, int node)
  23. {
  24.     struct kmem_cache *cache;
  25.     struct skb_shared_info *shinfo;
  26.     struct sk_buff *skb;
  27.     u8 *data;

  28.     /* 如果fclone被设置,则从skbuff_fclone_cache缓冲区中分配,如果没有设置
  29.      * 则从skbuff_head_cache缓冲区中分配。
  30.      * skbuff_fclone_cache:预先知道该skbuf会被clone,因此分配父子skbuf结构
  31.      * 并指向同一数据缓冲区
  32.      * skbuff_head_cache:该skbuf不会被clone */
  33.     cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;

  34.     /* Get the HEAD */
  35.     /* skbuf不能在DMA中分配,因此调用了gfp_mask & ~__GFP_DMA */
  36.     skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
  37.     if (!skb)
  38.         goto out;
  39.     /* 写缓存预取址 */
  40.     prefetchw(skb);

  41.     /* 边界对齐 */
  42.     size = SKB_DATA_ALIGN(size);
  43.     /* 分配skb的数据存储区 */
  44.     data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info),
  45.             gfp_mask, node);
  46.     if (!data)
  47.         goto nodata;
  48.     prefetchw(data + size);

  49.     /*
  50.      * Only clear those fields we need to clear, not those that we will
  51.      * actually initialise below. Hence, don't put any more fields after
  52.      * the tail pointer in struct sk_buff!
  53.      */
  54.     memset(skb, 0, offsetof(struct sk_buff, tail));
  55.     skb->truesize = size + sizeof(struct sk_buff);
  56.     /* 设置引用计数 */
  57.     atomic_set(&skb->users, 1);
  58.     skb->head = data;
  59.     skb->data = data;
  60.     skb_reset_tail_pointer(skb);
  61.     skb->end = skb->tail + size;
  62.     kmemcheck_annotate_bitfield(skb, flags1);
  63.     kmemcheck_annotate_bitfield(skb, flags2);
  64. #ifdef NET_SKBUFF_DATA_USES_OFFSET
  65.     skb->mac_header = ~0U;
  66. #endif

  67.     /* make sure we initialize shinfo sequentially */
  68.     shinfo = skb_shinfo(skb);
  69.     memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
  70.     atomic_set(&shinfo->dataref, 1);

  71.     /* 子skb的初始化 */
  72.     if (fclone) {
  73.         struct sk_buff *child = skb + 1;
  74.         /* 父子skb的总计数在两个skb结构的末尾 */
  75.         atomic_t *fclone_ref = (atomic_t *) (child + 1);

  76.         kmemcheck_annotate_bitfield(child, flags1);
  77.         kmemcheck_annotate_bitfield(child, flags2);
  78.         skb->fclone = SKB_FCLONE_ORIG;
  79.         /* 设置clone标记 */
  80.         atomic_set(fclone_ref, 1);

  81.         /* 子skb还未创建 */
  82.         child->fclone = SKB_FCLONE_UNAVAILABLE;
  83.     }
  84. out:
  85.     return skb;
  86. nodata:
  87.     kmem_cache_free(cache, skb);
  88.     skb = NULL;
  89.     goto out;
  90. }
阅读(3695) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

dreamice2011-04-02 10:07:58

高端内存如果映射了,当然也是可以的。

dreamice2011-03-02 09:54:57

GFree_Wind: 我有一个问题,skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);,这里不能使用DMA内存,我可以理解。但是我不理解为什么只排除DMA,难道.....
是的,可以使用的。

GFree_Wind2011-03-01 22:54:39

我有一个问题,skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);,这里不能使用DMA内存,我可以理解。但是我不理解为什么只排除DMA,难道__GFP_HIGHMEM高地址内存吗?
我不是内核工程师,所以对内核并不熟悉。