www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]RTL8139 網(wǎng)卡性能提升分析3162412793@qq.com技術(shù)交流QQ群:691976956?一、數(shù)據(jù)接收優(yōu)化數(shù)據(jù)接收優(yōu)化,主要是從如下幾個點出發(fā)進行驅(qū)動軟件的修改:接收中斷實現(xiàn)上下部方式,中

RTL8139 網(wǎng)卡性能提升分析

3162412793@qq.com

技術(shù)交流QQ群:691976956

?

一、數(shù)據(jù)接收優(yōu)化

數(shù)據(jù)接收優(yōu)化,主要是從如下幾個點出發(fā)進行驅(qū)動軟件的修改:

接收中斷實現(xiàn)上下部方式,中斷中通過發(fā)送同步信號量,收包由一個阻塞的任務(wù)來獲取到該信號量后開始進行接收的動作。

原始方式:

當(dāng)有網(wǎng)絡(luò)數(shù)據(jù)包接收完畢后,CPU會進中斷服務(wù)程序,中斷服務(wù)中,通過一個系統(tǒng)API函數(shù)來掛接收包任務(wù),那就是netJobAdd,該函數(shù)原形如下:

?? STATUS netJobAdd

???? (

???? FUNCPTR routine, /*在工作程序隊列中要加的例行程序*/

???? int param1, /*這個例行程序的第一個參數(shù)*/

???? int param2, /*這個例行程序的第二個參數(shù)*/

???? int param3, /*這個例行程序的第三個參數(shù)*/

???? int param4, /*這個例行程序的第四個參數(shù)*/

???? int param5,/*這個例行程序的第五個參數(shù)*/

???? )

而默認情況下,netJobAdd 接口將 routine 函數(shù)和相應(yīng)的參數(shù)傳遞到 tNet0 任務(wù)重被執(zhí)行,而該任務(wù)的優(yōu)先級是 50(VxWorks6.6版本是50, 不記得VxWorks5.5.1是多少了,也許是45),該優(yōu)先級固定死了,沒有提升的空間。

改進方式:

經(jīng)過上述的分析后,可以在中斷服務(wù)程序中釋放一個同步信號量,通知接收數(shù)據(jù)包的任務(wù)來收包,而該收包任務(wù)的優(yōu)先級可以自定義調(diào)整,也就是具體實現(xiàn)中斷上下部的方式。

?

LOCAL void rtl81x9Int

??? (

??? RTL81X9END_DEVICE? *pDrvCtrl

??? )

{

?

#if? 0

??? if (stat & RTL_IPT_RX_OK)

??? {

??? ????if (netJobAdd ((FUNCPTR)rtl81x9HandleRecvInt,(int) pDrvCtrl,0, 0, 0, 0) != OK)

??? ??????? DRV_LOG(DRV_DEBUG_INT, "xl: netJobAdd (rtl81x9HandleRecvInt) failedn",

0, 0, 0, 0, 0, 0);

??? ??? DRV_LOG(DRV_DEBUG_RX, "RTL_IPT_RX_OKn", 0, 0, 0, 0, 0, 0);*/

}

#endif

?

if (stat & RTL_IPT_RX_OK)

{

if(pDrvCtrl->unit == 0)

{

/*釋放信號量,開始接收數(shù)據(jù)*/

semGive(rtlNetTaskSemId0);

}

}

}

?????

收包任務(wù)的實現(xiàn)

?????

/*數(shù)據(jù)接收任務(wù)0*/

void rtlRecvTask0(RTL81X9END_DEVICE *?? pDrvCtrl)

{

??? FOREVER

??? {

??????? /* wait for somebody to wakeus up */

??? ???semTake (rtlNetTaskSemId0, WAIT_FOREVER);

??? ???rtl81x9HandleRecvInt(pDrvCtrl);

??? }

}

?

在start 函數(shù)中,啟動一個接受數(shù)據(jù)包的任務(wù),如下代碼所示。

?

VxWorks系統(tǒng)下的緩沖區(qū)管理機制的研究

網(wǎng)絡(luò)協(xié)議存儲池使用mBlk結(jié)構(gòu)、clBlk結(jié)構(gòu)、簇緩沖區(qū)和netBufLib提供的函數(shù)進行組織和管理。mBlk和clBlk結(jié)構(gòu)為簇緩沖區(qū)(cluster)中數(shù)據(jù)的緩沖共享和緩沖鏈接提供必要的信息。netBufLib例程使用mBlk和clBlk來管理cluster和引用cluster中的數(shù)據(jù),這些結(jié)構(gòu)體中的信息用于管理cluster中的數(shù)據(jù)并且允許他們通過引用的形式來實現(xiàn)數(shù)據(jù)共享,從而達到數(shù)據(jù)“零拷貝”的目的。

?

結(jié)構(gòu)體mBlk和clBlk及其數(shù)據(jù)結(jié)構(gòu)

mBlk是訪問存儲在內(nèi)存池中數(shù)據(jù)的最基本對象,由于mBlk僅僅只是通過clBlk來引用數(shù)據(jù),這使得網(wǎng)絡(luò)層在交換數(shù)據(jù)時就可以避免數(shù)據(jù)復(fù)制。只需把一個mBlk連到相應(yīng)mBlk鏈上就可以存儲和交換任意多的數(shù)據(jù)。一個mBlk結(jié)構(gòu)體包括兩個成員變量mNext和mNextPkt,由它們來組成縱橫兩個鏈表:mNext來組成橫的鏈表,這個鏈表中的所有結(jié)點構(gòu)成一個包(packet);mNextPkt來組成縱的鏈表,這個鏈表中的每個結(jié)點就是一個包(packet),所有的結(jié)點鏈在一起構(gòu)成一個包隊列,如圖1所示。

?


結(jié)構(gòu)體mBlk和clBlk的數(shù)據(jù)結(jié)構(gòu)如下所示:

struct mBlk

{

M_BLK_HDR??? mBlkHdr;????????????? /* header */

M_PKT_HDR??? mBlkPktHdr;???????? /* pkthdr */

CL_BLK *???????? pClBlk;????? /* pointer to cluster blk */

} M_BLK;

?

struct clBlk

{

???? CL_BLK_LIST? clNode;/* union of next clBlk */

????UINT?????? clSize;/* cluster size*/

????int??? clRefCnt;/*countof thecluster */

????struct netPool *? pNetPool;? /* pointer to the netPool */

} CL_BLK;

?

/* header at beginning of each mBlk */

struct mHdr

{

????struct mBlk *???? mNext;/* nextbuffer in chain */

? ???struct mBlk * mNextPkt;/* next chain inqueue/record */

???? char *mData;??????????????? /* location of data */

?int?mLen;/* amount of data in this mBlk */

?UCHAR?? mType;/* type of data in this mBlk */

?UCHAR?? mFlags;?????????????? /* flags; see below */

} M_BLK_HDR;

?

/* record/packet header in first mBlk of chain; valid if M_PKTHDR set */

struct?????? ???pktHdr

{

struct ifnet *???????? rcvif;/* rcvinterface */

int????? len;???????????? /* total packet length */

} M_PKT_HDR;

?

網(wǎng)絡(luò)協(xié)議存儲池的初始化

VxWorks在網(wǎng)絡(luò)初始化時給網(wǎng)絡(luò)協(xié)議分配存儲池并調(diào)用netPoolInit()函數(shù)對其初

始化,由于一個網(wǎng)絡(luò)協(xié)議通常需要不同大小的簇,因此它的存儲池也必須包含很多

簇池(每一個簇池對應(yīng)一個大小的簇)。如圖2所示。另外,每個簇的大小必須為2

的方冪,最大可為64KB(65536),存儲池的常用簇的大小為64,128,256,512,

1024比特,簇的大小是否有效取決于CL_DESC表中的相關(guān)內(nèi)容,CL_DESC表是由

netPoolInit()函數(shù)調(diào)用設(shè)定的。

?

網(wǎng)絡(luò)協(xié)議存儲池初始化后的結(jié)構(gòu)

?

使用netBufLib進行內(nèi)存池管理

?

netBufLib提供了mBlks與clBlks結(jié)構(gòu),其中mBlks指向clBlks,而clBlks指向

實際存貯數(shù)據(jù)的Cluster。不同層次之間交互數(shù)據(jù)可以直接通過傳遞mBlks鏈來進

行,而不用進行多余的數(shù)據(jù)拷貝。其中clBlks的作用是,記錄有多少個mBlks對其

進行了引用,當(dāng)引用為零時才可以釋放。不同的mBlks可以指向相同的clBlks,以

共享數(shù)據(jù)。

?

對于發(fā)送或接收的包可以由多個分開的內(nèi)存塊組成,也可以由一塊大的內(nèi)存塊組成。

因此對于一個包來說,它有一個mBlks鏈,鏈接著這個包的所有clusters。一個包

也應(yīng)該可以由一個大cluster組成,要是這樣的話,一個包就只要有一個mBlks就

行了。mBlks除鏈接著本身的所有的mBlks外,mBlks頭還鏈接著下一個包的mBlks

鏈的頭。

?

Clusters大小:

對于Clusters的大小,可以有不同型號。用于protocol的內(nèi)存池,可以有不同大

小的Clusters型號,但型號大小仍有限定(見參考資料)。用于driver的內(nèi)存池,

只有一種大小的Cluster。其大小與MTU(max transport unit)類似。

?

建立內(nèi)存池內(nèi)驟:

調(diào)用netPoolInit(),初始化緩沖池參數(shù)。預(yù)留mBlk,clBlk,cluster結(jié)構(gòu)空間等。

步應(yīng)在初始化時進行。

?

在Clusters中保存數(shù)據(jù):

1、在初始化時,調(diào)用netClusterGet()來預(yù)留Clusters空間。

2、當(dāng)組裝好數(shù)據(jù)或接收到數(shù)據(jù)則裝進Clusters中的一個。

3、調(diào)用netClBlkGet()來預(yù)留clBlk結(jié)構(gòu)。

4、調(diào)用netClBlkJoin()連接clBlk到包含數(shù)據(jù)的Cluster。

5、調(diào)用netMblkGet()預(yù)留mBlk結(jié)構(gòu)。

6、調(diào)用netMblkClJoin()連接mBlk結(jié)構(gòu)到clBlk。

?

釋放mBlks,clBlks,Clusters:

釋放mBlks鏈:netMblkClChainFree().這將釋放鏈中所有的mBlks。同時減少clBlks

中mBlks對其的引用,若減少至零,則clBlks及Clusters被釋放。釋放單獨

mBlk,clBlk,Cluster: netMblkClFree();

?

protocol與driver間傳數(shù)據(jù):

driver調(diào)用MUX的muxReceive();MUX調(diào)用protocol的stackRcvRtn()函數(shù);當(dāng)

muxReceive()正確返回后,driver確定數(shù)據(jù)己發(fā)送,接下來的buffer釋放,由協(xié)

議棧上層來完成。(The upper layers of the stack are responsible for freeing

the memory back to the driver’s memory pool.)

?

三、網(wǎng)絡(luò)收包分析

網(wǎng)卡收包有一系列需要注意的地方。

3.1 數(shù)據(jù)包的格式定義

數(shù)據(jù)包的格式如下。

??? /* cur_rx:

?????????? 31?????????? 16 15???????????? 0

??????????------------------------------------------------------????

??? 0:???? |????WORD1??? |???? WORD2????|? -----

??????????------------------------------------------------------???????

???????????? ???????????????????????????????????????_/

??? +4:??? ------------------------------------------------------

?????????? |??????????? DWORD3??????????? |

??????????------------------------------------------------------

?????????? WORD1:? Receive Status Flag;

?????????? WORD2:? Receive Package Length;

?????????? DWORD3: Receive PackageData Start Address.

???? */

??

?? 數(shù)據(jù)包開頭的4字節(jié)是接收的狀態(tài)標志和數(shù)據(jù)長度信息,后面才是數(shù)據(jù)的開始地址,

也就是說,拷貝數(shù)據(jù)的地址從當(dāng)前的指針位置 cur_rx + 4 開始,尾部是4字節(jié)的幀校驗序列 FCS (Frame Check Sequence), FCS 采用32位CRC循環(huán)冗余校驗對從"目標MAC地址"字段到"數(shù)據(jù)"字段的數(shù)據(jù)校驗,一般該數(shù)據(jù)沒有使用。

?

數(shù)據(jù)拷貝

當(dāng)前一幀數(shù)據(jù)的長度信息是存放在位置指針的頭四個字節(jié)中的,具體如上所述。

獲取到的長度包含了4字節(jié)的狀態(tài)信息,然后是數(shù)據(jù),然后是4字節(jié)的 FCS。

拷貝數(shù)據(jù)動作:

如果沒有跨尾,則直接拷貝即可。

??? memcpy (pNewCluster, readPtr + 4,len);???

??? 計算下一次DMA數(shù)據(jù)存放的地址;

??? cur_rx = (cur_rx + len + 4 + 3)& ~3;

如果有跨尾,則分兩次拷貝

wrapSize = (int) ((readPtr + len) - (pDrvCtrl->ptrRxBufSpace +RTL_RXBUFLEN));

/* Copy in first section of message as stored */

/* at the end of the ring buffer?????????? ? */

memcpy (pNewCluster, readPtr + 4, len-wrapSize-4);

/* Copy in end of message as stored */

/* at the start of the ring buffer?*/

memcpy (pNewCluster +len - wrapSize - 4, pDrvCtrl->ptrRxBufSpace,wrapSize);

/* there have some error compiler's bug in this line*/

/* If I just copy the correct bytes the last two bytes will*/

/* have some trouble, so I copy extra bytes to fix the CPU or*/

/* OS's bug vic??????????????????? */

?

計算下一次DMA數(shù)據(jù)存放的地址;

??? cur_rx = (wrapSize + 4 + 3) &~3;

3.2 數(shù)據(jù)接收由硬件DMA從FIFO到主內(nèi)存后,提交給 pMblk 的內(nèi)存鏈之Cluster,

最理想的是實現(xiàn)“零拷貝”。

?

?

?

原始方式:

網(wǎng)卡MAC接收到數(shù)據(jù)后,先進入到內(nèi)部的64K+16字節(jié)的FIFO,然后由 DMA直接將 FIFO中的數(shù)據(jù)通過PCI Master 的方式來傳遞到主存,主存為一個環(huán)形的內(nèi)存緩沖區(qū),如上述圖所示。當(dāng)有完整的數(shù)據(jù)包過來后,通過中斷通知CPU,進入到中斷服務(wù)程序處理接收邏輯。

首先讀取接收狀態(tài),如果發(fā)現(xiàn)是發(fā)送中斷,則直接調(diào)用發(fā)送中斷服務(wù)程序,如果是接收中斷,且沒有發(fā)現(xiàn)接收錯誤,則發(fā)送同步信號量,收包任務(wù)被激活,進入到收包程序。

?

收包程序?qū)⒆x命令寄存器,獲取到 bit 0 的數(shù)值,如果該數(shù)值一直為0,則表示緩沖區(qū)中還有數(shù)據(jù)沒有取完,通過一個循環(huán)操作解析數(shù)據(jù)包,拷貝到 Cluster, 連接到clBlk, 最后連接到 mBlk, 然后提交到協(xié)議棧,直到取完為止,中間有一系列的容錯處理,還有注意內(nèi)存拷貝的指針計算等操作,都在里面。

?

改進方式:

上述的原始的方式,存在一個很明顯的問題,那就是進行了數(shù)據(jù)的拷貝。分配給DMA

的環(huán)行緩沖區(qū)地址是獨立的,數(shù)據(jù)首先會到這里,而我們最終提交給協(xié)議棧的內(nèi)存空間卻是另一個內(nèi)存塊,該內(nèi)存塊也是由用戶自己分配的,那么就需要進行從第一個內(nèi)存地址空間到另一個內(nèi)存地址空間的搬移,這樣大大地浪費了操作系統(tǒng)的時間,效率自然就降低了。

鑒于此,可以考慮一點,能否在由DMA環(huán)行緩沖區(qū)拷貝數(shù)據(jù)到Cluster 改為直接使用DMA的環(huán)行緩沖區(qū)作為內(nèi)存管理 Cluster 的新地址,說的比較多,估計也聽的有點不太明白,看下面的對比圖。

?

原始的操作方式

?

?

現(xiàn)在的操作方式

?

這樣直觀看了后,發(fā)現(xiàn)效率肯定有明顯的差別,前者需要內(nèi)存拷貝,后者不需要內(nèi)存拷貝。

具體的,在實現(xiàn)后者的設(shè)計思想上,有一些技巧需要考慮的。因為硬件設(shè)計特點,當(dāng)DMA環(huán)行緩沖區(qū)到尾后,如果條件允許,數(shù)據(jù)將會自動從DMA緩沖區(qū)頭開始存放數(shù)據(jù),目前設(shè)置的DMA緩沖區(qū)大小為 64K+16(16字節(jié)用于軟件自動調(diào)節(jié)下次存放的指針位置,確保是對齊的地址)。

這樣的話,如果按照提交指針的方式,則會有點問題,為什么呢?因為,恰巧當(dāng)數(shù)據(jù)包跨緩沖區(qū)尾和區(qū)頭的時候,這樣提交指針就會出現(xiàn)數(shù)據(jù)錯誤。具體原因分析如下:

雖然分配了一段地址給DMA環(huán)行緩沖區(qū),看起來是一個環(huán),但實際上,地址不是連接在一起的,而是一塊內(nèi)存,只是通過配置了寄存器后告訴硬件DMA,到內(nèi)存的尾了,就自動從頭開始存放而已。

?

?

如果接收到的數(shù)據(jù)包沒有跨尾,則可以直接提交當(dāng)前的入口指針即可,否則,如果出現(xiàn)了跨尾,則還是按照上述的操作會出現(xiàn)問題,看下圖。

?

?

如果出現(xiàn)跨尾,則直接提交 Data Pointer 后將使用了后面虛線的內(nèi)容,而不會使用前面的數(shù)據(jù)塊,暫時無法實現(xiàn)自動回頭的功能。

有兩種方式解決該問題,一種就是,在網(wǎng)卡驅(qū)動 start函數(shù)中,動態(tài)分配一個1518+8

字節(jié)的內(nèi)存塊,然后將上述出現(xiàn)了分離的數(shù)據(jù)拷貝到該內(nèi)存塊,然后將該內(nèi)存首地

址join到 clBlk 即可;另一種就是,在分配DMA環(huán)行緩沖區(qū)的時候,在原來的64K+16字節(jié)的基礎(chǔ)上,多分配1518+8字節(jié)的空間,如上述的虛線框所示,這樣的話,只需要將上述的最頭上的蘭色框的數(shù)據(jù)拷貝到DMA End地址之后,然后可以直接提交 Data Pointer ?join到 clBlk 即可。

??????

但是在實際中,按照后者操作的方式,出現(xiàn)了一些問題,需要解決。

?

問題點如下:

?

按照后者的方式操作后,PING 沒有問題,小量發(fā)送數(shù)據(jù)包也沒有問題,當(dāng)使用發(fā)包工具大量發(fā)包的時候,只要在串口控制臺上按下任何的命令,都會出現(xiàn)如下的錯誤信息:

?

data access

Exception current instruction address: 0x001ebce4

Machine Status Register: 0x00003032

Data Access Register: 0x5fff0017

Condition Register: 0x42048042

Data storage interrupt Register: 0x40000000

Task: 0x273b470 "tRtlRxTask0"

0x273b470 (tRtlRxTask0): task 0x273b470 has had a failure and has beenstopped.

0x273b470 (tRtlRxTask0): fatal kernel task-level exception!

?

通過DEBUG方式,依次查找出現(xiàn)問題的原因。

上述錯誤信息指令地址在0x001ebce4,一般而言,如果修改代碼,重新編譯,該地址將會變化。

?

在命令行下查看了該地址信息,如下:

?

-> lkAddr 0x001ebce4

?

0x001eb290 netMblkChainDup??????????text???

0x001ec398 muxTxRestart?????????????text???

0x001ec48c muxReceive???????????????text???

0x001ec6a0 muxSend??????????????????text???

0x001ec6d8 _muxTkSendNpt????????????text???

0x001ec7c0 _muxTkSendEnd????????????text???

0x001eca98 muxTkSend????? ???????????text???

0x001ecac8 muxTkReceive?????????????text???

0x001ecd04 ipcom_sem_wait???????????text???

0x001ecd28 ipcom_mutex_lock?????????text???

0x001ecd4c ipcom_sem_interrupt_flush text???

0x001ecd6c ipcom_sem_flush??????????text???

value = 0 = 0x0

?

問題點應(yīng)該可以鎖定在 netMblkChainDup 這個函數(shù)中。

?

可以使用 tt 命令跟蹤下。

跟蹤發(fā)現(xiàn),在 netMblkChainDup 函數(shù)里面出現(xiàn)了異常。

?

-> tt tRtlRxTask

?

0x000962f8 vxTaskEntry? +0x48 :rtlRecvTask0 (0x270d9e8)

0x00030324 rtlRecvTask0 +0x28 : semTake ()

0x0016d9d4 semTake????? +0x138:semBTake ()

value = 0 = 0x0

?

正常情況下,如上述所示。

?

如果出現(xiàn)了上述的數(shù)據(jù)非法訪問錯誤,則網(wǎng)絡(luò)收包任務(wù)將被迫停止。通過 tt 命令后就可以發(fā)現(xiàn),通過一系列的函數(shù)調(diào)用后,最后的執(zhí)行函數(shù)為netMblkChainDup,估計在該函數(shù)中,釋放了一些內(nèi)存,然后繼續(xù)使用導(dǎo)致。

?

但是有一點不太明白的是,如在 shell下不執(zhí)行任何的操作,網(wǎng)絡(luò)可以承受不停的沖擊,沒有什么問題,如果一旦操作后,系統(tǒng)就掛死了。

?

反匯編,找到該指令的地址所在:

可以使用 objdumpppc –D vxWorks>img.s

?

-> objdumpppc –D vxWorks >img.s

?

?

找到目標地址:

?

?

如何實現(xiàn)DMA緩沖區(qū)和 pMblk 的緩沖區(qū)管理鏈中的 Cluster的內(nèi)存共享,以達到“零拷貝”。

該部分的內(nèi)存共享,如上述分析,可能存在一些問題。實際測試的結(jié)果是,網(wǎng)絡(luò)在該情況下可以正常的收發(fā)包,但是,內(nèi)存可能出現(xiàn)了問題,或者操作系統(tǒng)的任務(wù)棧遭受了破壞,shell 下無法輸入命令,只要一輸入,系統(tǒng)就掛死了。同上3),原因還沒有找到。

?

借助以前開發(fā)VxWorks系統(tǒng)下的 1394驅(qū)動經(jīng)驗,能否借助于消息隊列來提升性能?

借助于 Linux 系統(tǒng)下面的接收機制

初始化使能中斷后,第一次無論是發(fā)送完成或接收中斷,進去后,關(guān)閉所有中斷,然后讀取中斷狀態(tài)寄存器,判斷是何種類型的中斷,如果是發(fā)送完成中斷,則在退出中斷之前,僅僅打開發(fā)送中斷,如果是接收中斷,則在退出中斷之前,不使能接收中斷,等接收數(shù)據(jù)包任務(wù)完成后再使能該中斷。

總結(jié)為一句話,發(fā)送中斷按照原始的處理方式,而接收中斷第一次進中斷后,屏蔽該中斷類型,中斷服務(wù)程序釋放一個同步信號量,激活收包任務(wù),采用輪詢的方式直到將數(shù)據(jù)包接收完畢后再打開接收中斷。

?

二、數(shù)據(jù)發(fā)送優(yōu)化

在閱讀發(fā)送函數(shù)時,發(fā)現(xiàn)協(xié)議棧(以下簡稱上層),將pMblk 指針傳遞給發(fā)送函數(shù),然后再查詢是否有可用的發(fā)送描述符后,對上層的數(shù)據(jù)包進行拷貝到發(fā)送描述符對應(yīng)的緩沖區(qū),設(shè)置發(fā)送,等待完成。

這里對速度影響比較大的點就是,執(zhí)行了數(shù)據(jù)的拷貝動作,參考如下代碼:

LOCAL STATUS rtl81x9Send

??? (

??? RTL81X9END_DEVICE?????????? *pDrvCtrl,?????????? /* device ptr */

??? M_BLK_ID???????????????????? pMblk?????????????? /* data to send */

)

{

??? ???????????/* Replace this code !! */

??????? #if 0

??????????????? len = netMblkToBufCopy(pMblk, pBuf, NULL);

???????????????netMblkClChainFree(pMblk);

??????? #endif

??????????????? len =pMblk->mBlkHdr.mLen;

???????????????

??? ??????????? ???/*pMblk->mBlkPktHdr.len = len;*/

???????????????

??????????????? len = max (len, ETHERSMALL);

??????????????? tx_val = len + (0x38<< 16);

?

/* pass pointer to the TX desc register */

??????????????? pBuf =pMblk->mBlkHdr.mData;

??????????????? …

??????????????? /* Flush the writepipe */

??????? ????????CACHE_PIPE_FLUSH ();

??????? ????????netMblkClChainFree(pMblk); /* Add byalex */

}

上述代碼中,紅色字體部分是原始的代碼,需要進行拷貝,這樣會影響到發(fā)送性能,修改為藍色字體部分,基本上實現(xiàn)了“零拷貝”,經(jīng)過 EtherPeek 發(fā)包軟件測試,沒有問題。

?


本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉