0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

sk_buff內(nèi)存空間布局情況與相關(guān)操作(三)

麥辣雞腿堡 ? 來(lái)源:技術(shù)簡(jiǎn)說(shuō) ? 作者:董旭 ? 2023-07-30 16:48 ? 次閱讀

2、非線性區(qū)域

在1、中,可以看到每張sk_buff的圖: 在end指針緊挨著一個(gè)非線性區(qū)域 ;

在struct sk_buff中沒(méi)有指向skb_shared_info結(jié)構(gòu)的指針,利用end指針,,可以用skb_shinfo宏來(lái)訪問(wèn):

#define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB)))

其中skb_end_pointer函數(shù)如下,返回end指針

static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
 return skb- >end;
}

具體地,struct skb_shared_info如下:

struct skb_shared_info {
 __u8  __unused;
 __u8  meta_len;

    //數(shù)組frags包含的元素個(gè)數(shù)
 __u8  nr_frags;
 __u8  tx_flags;
 unsigned short gso_size;
 /* Warning: this field is not always filled in (UFO)! */
 unsigned short gso_segs;
 struct sk_buff *frag_list;
 struct skb_shared_hwtstamps hwtstamps;
 unsigned int gso_type;
 u32  tskey;

 /*
  * Warning : all fields before dataref are cleared in __alloc_skb()
  */
 
    //結(jié)構(gòu)skb_shared_info 的引用計(jì)數(shù)器
 atomic_t dataref;

 /* Intermediate layers must ensure that destructor_arg
  * remains valid until skb destructor */
 void *  destructor_arg;

 /* must be last field, see pskb_expand_head() */
 skb_frag_t frags[MAX_SKB_FRAGS];
};

其中skb_frag_t如下:

typedef struct skb_frag_struct skb_frag_t;

struct skb_frag_struct {
 struct {

    //指向文件系統(tǒng)緩存頁(yè)的指針
  struct page *p;
 } page;
#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)

  //數(shù)據(jù)起始地址在文件系統(tǒng)緩存頁(yè)中的偏移
 __u32 page_offset;
  //數(shù)據(jù)在文件系統(tǒng)緩存頁(yè)中使用的長(zhǎng)度
 __u32 size;
#else
 __u16 page_offset;
 __u16 size;
#endif
};

nr_frags,frags,frag_list與IP分片存儲(chǔ)有關(guān)。

frag_list的用法:

  • 用于在接收分組后鏈接多個(gè)分片,組成一個(gè)完整的IP數(shù)據(jù)報(bào)
  • 在UDP數(shù)據(jù)報(bào)輸出中,將待分片的SKB鏈接到第一個(gè)SKB中,然后在輸出過(guò)程中能夠快速的分片
  • 用于存放FRAGLIST類(lèi)型的聚合分散I/O數(shù)據(jù)包

判斷是否存在非線性緩沖區(qū):

  • 先說(shuō)明struct sk_buff中關(guān)于長(zhǎng)度的兩個(gè)字段
  1. len字段:無(wú)分片的報(bào)文,數(shù)據(jù)報(bào)文的大小
  2. data_len字段:存在分散報(bào)文,data_len表示分片的部分大小

如下所示,沒(méi)有開(kāi)啟分片的報(bào)文len = x,data_len = 0:

圖片

如下所示在Linux內(nèi)核中,使用skb_is_nonlinear函數(shù)判斷是否存在分片,即通過(guò)判斷data_len的大小是否為0:

static inline bool skb_is_nonlinear(const struct sk_buff *skb)
{
 return skb- >data_len;
}
  • 在沒(méi)有開(kāi)啟分片的報(bào)文中,數(shù)據(jù)包長(zhǎng)度在struct sk_buff中為len字段的大小,即data到tail的長(zhǎng)度,nf_frags為0,frag_list為NULL。

普通聚合分散I/O的報(bào)文:

采用聚合分散I/O的報(bào)文, frag_list為 NULL,nf_frags不等于0 ,說(shuō)明這不是一個(gè)普通的分片,而是聚合分散I/O的報(bào)文。

如下所示:

nr_frags為2,而frag_list為NULL,說(shuō)明這不是普通的分片,而是聚合分散I/O分片,數(shù)量為2,這兩個(gè)分片指向同一物理分頁(yè),各自在分頁(yè)中的偏移和長(zhǎng)度分別是0/S1和S1/S2。

圖片

FRAGLIST類(lèi)型的分散聚合I/O的報(bào)文:

采用FRAGLIST類(lèi)型的分散聚合I/O報(bào)文, ** frag_list不為NULL,nf_frags等于0 ,** 數(shù)據(jù)長(zhǎng)度len為x+S1,data_len為S1,

圖片

以上從struct sk_buff的四大指針以及操作、非線性區(qū)域?qū)μ捉幼志彺?socket buffer)進(jìn)行分析,更多sk_buff的分析、實(shí)操等將在以后的文章中梳理。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5059

    文章

    18973

    瀏覽量

    302042
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11207

    瀏覽量

    208721
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2966

    瀏覽量

    73814
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux sk_buff四大指針與相關(guān)操作

     在以上文章中,沒(méi)有分析過(guò)Linux內(nèi)核網(wǎng)絡(luò)關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)-套接字?jǐn)?shù)據(jù)緩存struct sk_buff,本文將第一次分享到sk_buff,但鑒于其在內(nèi)核網(wǎng)絡(luò)中一些復(fù)雜情況,本次只簡(jiǎn)單介紹sk_
    發(fā)表于 10-13 17:23 ?4443次閱讀
    Linux <b class='flag-5'>sk_buff</b>四大指針與<b class='flag-5'>相關(guān)</b><b class='flag-5'>操作</b>

    使用rt_malloc申請(qǐng)內(nèi)存空間失敗,顯示沒(méi)有內(nèi)存怎么解決?

    + net_server + crclib) 的情況下,還有2個(gè)堆棧空間2048的應(yīng)用線程,使用rt_malloc申請(qǐng)內(nèi)存空間失敗,顯示沒(méi)有內(nèi)存。經(jīng)測(cè)試,只能申請(qǐng)1200bytes
    發(fā)表于 07-04 08:10

    Linux內(nèi)存點(diǎn)滴 用戶進(jìn)程內(nèi)存空間

    , Data+Stack size (kb)nFLT, Page Fault countnDRT, Dirty Pages count盡管有注釋?zhuān)廊桓杏X(jué)有些晦澀,不知所指何意?進(jìn)程內(nèi)存空間正在運(yùn)行的程序,叫進(jìn)程。每個(gè)
    發(fā)表于 08-14 16:23

    嵌入式linux TCP/IP協(xié)議棧概述

    ;unsigned char *head,//緩存區(qū)的頭指針*data;//有效數(shù)據(jù)頭指針...};sk_buff相關(guān)操作函數(shù)
    發(fā)表于 12-07 10:05

    DM8127使用SWOSD_TI_alloc()分配內(nèi)存空間怎么加大?

    DM8127使用SWOSD_TI_alloc()分配內(nèi)存空間不夠,請(qǐng)問(wèn)在什么文件里怎樣修改加大內(nèi)存空間???
    發(fā)表于 04-16 10:56

    stm32 使用u*** host庫(kù)占用內(nèi)存空間很大?。?!

    如何解決stm32 使用u*** host庫(kù)占用內(nèi)存空間很大的問(wèn)題呢???
    發(fā)表于 01-22 16:44

    ARM32 Linux的內(nèi)存布局

    看我們實(shí)際上內(nèi)存布局是怎么樣的?Linux內(nèi)核在啟動(dòng)時(shí),會(huì)打印出內(nèi)核內(nèi)存空間布局圖,下面是ARM IMX6平臺(tái)打印出來(lái)的內(nèi)存空間布局圖這部
    發(fā)表于 04-24 14:20

    RTThread的動(dòng)態(tài)內(nèi)存空間該如何去分配呢

    配的Heap_Size,而使用rt_malloc申請(qǐng)到的則是RTT分配的空間然后有以下幾個(gè)問(wèn)題1、如果是動(dòng)態(tài)創(chuàng)建線程,那線程中的局部變量是位于RTT分配的動(dòng)態(tài)內(nèi)存空間中還是位于棧空間中?2、如果使用一些第
    發(fā)表于 08-31 14:34

    freertos怎么釋放任務(wù)的內(nèi)存空間

    freertos怎么釋放任務(wù)的內(nèi)存空間
    發(fā)表于 10-12 07:20

    Linux網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序

    當(dāng)要發(fā)送數(shù)據(jù)包的時(shí)候,內(nèi)核必須建立一個(gè)包含傳輸數(shù)據(jù)的sk_buff,然后將sk_buff交給下層,各層在sk_buff遞交給下一層,各層在sk_buff中添加不同的協(xié)議貞頭,直到交給網(wǎng)
    發(fā)表于 05-10 11:15 ?1810次閱讀

    如何讓你的手機(jī)省出內(nèi)存空間

    大家都知道,手機(jī)使用久了就會(huì)變得很卡頓,除了手機(jī)本身“老化”之外,還有一個(gè)重要的原因就是內(nèi)存堆積的太多了。事實(shí)上占用手機(jī)內(nèi)存的無(wú)非就是照片、視頻、微信等等,如果好好處理一下這幾個(gè)方面的問(wèn)題,相信你的手機(jī)一定能省出不少內(nèi)存空間,下
    的頭像 發(fā)表于 02-13 14:07 ?4167次閱讀

    網(wǎng)卡的Ring Buffer詳解

    DMA 將 NIC 接收的數(shù)據(jù)包逐個(gè)寫(xiě)入 sk_buff ,一個(gè)數(shù)據(jù)包可能占用多個(gè) sk_buff , sk_buff 讀寫(xiě)順序遵循FIFO(先入先出)原則。
    的頭像 發(fā)表于 03-17 14:25 ?1466次閱讀

    網(wǎng)卡的Ring Buffer詳解

    DMA 將 NIC 接收的數(shù)據(jù)包逐個(gè)寫(xiě)入 sk_buff ,一個(gè)數(shù)據(jù)包可能占用多個(gè) sk_buff , sk_buff 讀寫(xiě)順序遵循FIFO(先入先出)原則。
    的頭像 發(fā)表于 04-04 09:15 ?1103次閱讀

    sk_buff內(nèi)存空間布局情況相關(guān)操作(一)

    :報(bào)文數(shù)據(jù),保存了實(shí)際網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù),在內(nèi)核協(xié)議棧起承上啟下的作用,也有很多值得關(guān)注的sk_buff操作。 1、sk_buff四大指針與相關(guān)操作
    的頭像 發(fā)表于 07-30 16:43 ?1136次閱讀
    <b class='flag-5'>sk_buff</b><b class='flag-5'>內(nèi)存空間布局</b><b class='flag-5'>情況</b>與<b class='flag-5'>相關(guān)</b><b class='flag-5'>操作</b>(一)

    sk_buff內(nèi)存空間布局情況相關(guān)操作(二)

    操作tailroom中用戶數(shù)據(jù)塊區(qū)域:skb_put用于修改指向數(shù)據(jù)區(qū)末尾的指針tail: void *skb_put( struct sk_buff *skb, unsigned int len
    的頭像 發(fā)表于 07-30 16:47 ?706次閱讀
    <b class='flag-5'>sk_buff</b><b class='flag-5'>內(nèi)存空間布局</b><b class='flag-5'>情況</b>與<b class='flag-5'>相關(guān)</b><b class='flag-5'>操作</b>(二)