pskb_may_pull():函数用来保证skb的线性数据长度至少有len的大小。 skb_header_pointer():从skb字段中获取指定长度到内容到缓存中。 skb_shinfo(): #define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB)))返回end指针,即指向skb_shared_info数据结构(非线性区)。
/* tx-scatter-gather on 表示硬件可以支持分散聚合,而该功能是基于 skb_shinfo(skb)->frags[i] 来实现*/ ethtool -k ens39f0 | grep scatter scatter-gather: on tx-scatter-gather: on tx-scatter-gather-fraglist: off [fixed] /* 关闭 scatter gather */ $ sudo ethtool -K ens39f0 sg off Ac...
skb_shinfo(skb)->frag_list =clone; } } pull_pages: eat=delta; k=0;//释放frags中的pagefor(i =0; i < skb_shinfo(skb)->nr_frags; i++) {if(skb_shinfo(skb)->frags[i].size <=eat) { put_page(skb_shinfo(skb)->frags[i].page); eat-= skb_shinfo(skb)->frags[i].size; }e...
//分配新的skb->data,将旧的skb->data、skb_shinfo(skb)->frags、skb_shinfo(skb)->frag_list中的内容拷贝到新skb->data的连续内存空间中,释放frags或frag_list //其中frags用于支持分散聚集IO,frags_list用于支持数据分片 1.1 int __skb_linearize(struct sk_buff *skb, int gfp_mask) { unsigned int ...
skb_shinfo(skb)->nr_frags =0; skb1->data_len = skb->data_len; skb1->len += skb1->data_len; skb->data_len =0; skb->len =len; skb_set_tail_pointer(skb, len);//下面把实现函数代码注释进来,方便理解//static inline void skb_set_tail_pointer(struct sk_buff *skb, const int of...
shinfo = skb_shinfo(skb); memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); atomic_set(&shinfo->dataref, 1); if (fclone) { /* 如果是fclone cache的话,那么skb的下一个buf,也将被分配*/ struct sk_buff *child = skb + 1; ...
skb的内存空间划分为线性区(head-end)和非线性区(frags和frag_list),非线性区是通过skb_shinfo管理的。 理解skb_shinfo至关重要,它位于skb尾部,其中frags用于Scatter Gather(SG)功能,这是一种在TX时通过硬件加速数据发送的方式。SG通过软件生成分散的数据块,硬件进行DMA读取和合并,例如IXGBE驱动通过dma_map_single...
第一是skb_shared_info在sk_buff是无法直接找到的,在访问的时候需要借助skb_shinfo宏来实现,关于NET_SKBUFF_DATA_USES_OFFSET可参考[8]: #defineskb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB))) #ifdefNET_SKBUFF_DATA_USES_OFFSET ...
skb_shinfo(skb)->dataref 含义 dataref表示对共享数据区的引用数目。通常克隆报文的时候,所有报文共享一个数据区。如下图所示,dataref = 2,表示有两个引用指向该区域。 dataref 共享数据 数据区 技术 原创 wx61307a0120efd 2021-09-02 16:21:50 ...
vaddr + skb_shinfo(skb)->frags[i].page_offset+ offset - start, copy); kunmap_skb_frag(vaddr); if ((len -= copy) == 0) return 0; offset += copy; to += copy; } start = end; } // 拷贝其他碎片skb中的数据部分 if (skb_shinfo(skb)->frag_list) { ...