/****************************************************
* dev_alloc_skb - 分配内存为接受的包
* @length: 分配的长度
* GFP_ATOMIC:原子类型,此函数经常用于终端上下文中
***************************************************/
struct sk_buff *dev_alloc_skb(unsigned int length)
{
return __dev_alloc_skb(length, GFP_ATOMIC);
}
EXPORT_SYMBOL(dev_alloc_skb);
#ifndef NET_SKB_PAD
#define NET_SKB_PAD 32
#endif
/*************************************************************
*gfp_mask: get_free_pages mask, passed to alloc_skb
*alloc_skb()增加32字节的空间,优化读写的效率
**************************************************************/
static inline struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask)
{
struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
if (likely(skb))
skb_reserve(skb, NET_SKB_PAD);
return skb;
}
static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority)
{
return __alloc_skb(size, priority, 0, -1);
}
/****************************************************************************
* __alloc_skb 分配network的缓冲区
* @size: 分配的内存大小
* @gfp_mask: 分配的标签
* @fclone: 从fclone缓存分配内存并分配一个克隆的skb
* @node: 分配的节点号,一般为-1
****************************************************************************/
struct sk_buff *__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;
cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
/* 获取头 */
skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
if (!skb)
goto out;
size = SKB_DATA_ALIGN(size); //字节对齐
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, tail));
skb->truesize = size + sizeof(struct sk_buff);
atomic_set(&skb->users, 1);
skb->head = data;
skb->data = data;
skb_reset_tail_pointer(skb);
skb->end = skb->tail + size;
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->tx_flags.flags = 0;
shinfo->frag_list = NULL;
memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
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;
}
EXPORT_SYMBOL(__alloc_skb);
/**
* @skb: buffer to alter
* @len: bytes to move
*
* Increase the headroom of an empty &sk_buff by reducing the tail
* room. This is only allowed for an empty buffer.
*/
static inline void skb_reserve(struct sk_buff *skb, int len)
{
skb->data += len;
skb->tail += len;
}
分享到:
相关推荐
下载的stl_alloc.h源码,自己加了注释,有助于理解stl空间配置器
cdev_alloc函数[归类].pdf
《侯捷 - C++内存管理机制_60_侯捷》27.G2.9std_alloc源码剖析(上)
Tensorflow2.0 之Could not create cudnn handle: CUDNN_STATUS_ALLOC_FAILED问题 问题描述: 在tensorflow2.0的学习过程中,遇到了Could not create cudnn handle: CUDNN_STATUS_ALLOC_FAILED,发现这个问题是我在...
idx_alloc_indexalloc_源码
《C++内存管理机制_60_侯捷》21.G2.9std_allocVSG4.9__pull_alloc
主要讲3个dma的函数,dma_alloc_coherent,dma_poll_create, dma_map_single使用实例
stats_alloc用于Rust中全局分配器的工具中间件,用于测试验证有关分配模式的假设,以及stats_alloc用于Rust中全局分配器的工具中间件,用于测试验证关于分配模式的假设,并可能在生产负载中监视内存泄漏。...
skb = dev_alloc_skb(pkt->datalen + 2); if (!skb) { if (printk_ratelimit()) printk(KERN_NOTICE "snull rx: low on mem - packet dropped\n"); priv->stats.rx_dropped++; goto out; } skb_reserve(skb,...
基于SAP和TOC的瓶颈识别 基于SAP和TOC的瓶颈识别
《侯捷 - C++内存管理机制_60_侯捷》30.G2.9std_alloc观念大整理
《侯捷 - C++内存管理机制_60_侯捷》25.G2.9std_alloc运行一瞥06-10
《侯捷 - C++内存管理机制_60_侯捷》28.G2.9std_alloc源码剖析(中)
consistent DMA memory allocation
MN10300 Dynamic DMA mapping support.
一种高速Index分配逻辑,无需链表支持即可完成index的分配
SRAM allocator for Blackfin on-chip memory.
an arena which memory may be allocated.
This test purpose is simply to check Standard header independancy that is to say that the header can be included alone without any previous include.
Android底层源码分析_Binder,Android底层源码分析_Binder