日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

32位网卡驱动 2008_DPDK之网卡收包流程

發布時間:2024/4/18 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 32位网卡驱动 2008_DPDK之网卡收包流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.導讀

一個網絡報文從網卡接收到被應用處理,中間主要需要經歷兩個階段:

  • 階段一:網卡通過其DMA硬件將收到的報文寫入到收包隊列中(入隊)
  • 階段二:應用從收包隊列中讀取報文(出隊)

下面以ixgbe網卡在dpdk框架下工作為例,分別介紹下收包隊列的構造、啟動和收包三個流程。

2.構造

收包隊列的構造主要是通過調用網卡隊列設置函數rte_eth_rx_queue_setup(dpdk rte_ethdev.h)來完成。

收包隊列的結構體為ixgbe_rx_queue,該結構體里包含兩個重要的環形隊列rx_ring和sw_ring,rx_ring和sw_ring的關系可以簡單如下認為。

  • rx_ring主要存儲報文數據的物理地址,物理地址供網卡DMA使用,也稱為DMA地址(硬件使用物理地址,將報文copy到報文物理位置上)。
  • sw_ring主要存儲報文數據的虛擬地址,虛擬地址供應用使用(軟件使用虛擬地址,讀取報文)。

其中,報文數據的物理地址可以由報文數據的虛擬地址轉化得到。下面詳細介紹下rx_ring與sw_ring兩個隊列的構成。

2.1.rx_ring

ixgbe_adv_rx_desc

ixgbe_adv_rx_desc

......

ixgbe_adv_rx_desc

rx_ring是由一個動態申請的數組構建的環形隊列,隊列的元素是ixgbe_adv_rx_desc類型,隊列的長度為(4096+4-1)。

  • pkt_addr:報文數據的物理地址,網卡DMA將報文數據通過該物理地址寫入對應的內存空間。
  • hdr_addr:報文的頭信息,hdr_addr的最后一個bit為DD位,因為是union結構,即status_error的最后一個bit也對應DD位。

DD位(Descriptor Done Status)用于標志標識一個描述符buf是否可用。

  • 網卡每次來了新的數據包,就檢查rx_ring當前這個buf的DD位是否為0,如果為0那么表示當前buf可以使用,就讓DMA將數據包copy到這個buf中,然后設置DD為1。如果為1,那么網卡就認為rx_ring隊列滿了,直接會將這個包給丟棄掉,記錄一次imiss。(0->1)
  • 對于應用而言,DD位使用恰恰相反,在讀取數據包時,先檢查DD位是否為1,如果為1,表示網卡已經把數據包放到了內存中,可以讀取,讀取完后,再放入一個新的buf并把對應DD位設置為0。如果為0,就表示沒有數據包可讀。(1->0)

2.2.sw_ring

ixgbe_rx_entry

ixgbe_rx_entry

……

ixgbe_rx_entry

sw_ring是由一個動態申請的數組構建的環形隊列,隊列的元素是ixgbe_rx_entry類型,隊列的大小可配,一般最大可配4096。

  • mbuf:報文mbuf結構指針,mbuf用于管理一個報文,主要包含報文相關信息和報文數據。

3.啟動

收包隊列的啟動主要是通過調用rte_eth_dev_start(dpdk rte_ethdev.h)函數完成,收包隊列初始化的核心流程如下。

循環從mbuf pool中申請mbuf,從mbuf中得到報文數據對應的物理地址,物理地址存入rx_ring中,mbuf指針存入sw_ring中。其中通過rxd->read.hdr_addr = 0,完成了DD位設置為0。

一切ok后,就可以開始收包了。

3.收包

收包由網卡入隊和應用出隊兩個操作完成。

3.1入隊

入隊的操作是由網卡DMA來完成的,DMA(Direct Memory Access,直接存儲器訪問)是系統和網卡(外設)打交道的一種方式,該種方式允許在網卡(外部設備)和系統內存之間直接讀寫數據,這樣能有效減輕CPU的工作。

網卡收到報文后,先存于網卡本地的buffer-Rx(Rx FIFO)中,然后由DMA通過PCI總線將報文數據寫入操作系統的內存中,即數據報文完成入隊操作。(PS:PCIe總線可能成為網卡帶寬的瓶頸)

3.2.出隊

應用調用rte_eth_rx_burst(dpdk rte_ethdev.h)函數開始批量收包,最大收包數量由參數nb_pkts決定(比如設置為64)。其核心流程由ixgbe_recv_pkts(dpdk ixgbe_rxtx.c)實現,從收包隊列rx_tail位置開始收,循環讀取一個報文、填空一個報文(空報文數據),讀取64個后,重新標記rx_tail的位置,完成出隊操作,將收取的報文作返回供應用處理。代碼簡化如下。

-------------------------------------------------

struct rte_mbuf *rxm;

//從隊列的tail位置開始取包

rx_id = rxq->rx_tail;

//循環獲取nb_pkts個包

while (nb_rx < nb_pkts)

{

......

rxdp = &rx_ring[rx_id];

//檢查DD位是否為1,是1則說明該位置已放入數據包,否則表示沒有報文,退出

staterr=rxdp->

wb.upper.status_error;

if(!(staterr

&rte_cpu_to_le_32(IXGBE_RXDADV_STAT_DD)))

break;

rxd = *rxdp;

//申請一個mbuf(nmb),用于交換

nmb = rte_mbuf_raw_alloc(rxq->mb_pool);

//從sw_ring中讀取一個報文mbuf(存入rxm)

rxe = &sw_ring[rx_id];

rxm = rxe->mbuf;

//往sw_ring中填空一個新報文mbuf(nmb)

rxe->mbuf = nmb;

//新mbuf對應的報文數據物理地址填入rx_ring對應位置,并將hdr_addr置0(DD位置0)

dma_addr =rte_cpu_to_le_64

(rte_mbuf_data_dma_addr_default(nmb));

rxdp->read.hdr_addr = 0;

rxdp->read.pkt_addr = dma_addr;

//對讀取mbuf的報文信息進行初始化

rxm->pkt_len = pkt_len;

rxm->data_len = pkt_len;

rxm->port = rxq->port_id;

......

//讀取的報文mbuf存入rx_pkts

rx_pkts[nb_rx++] = rxm;

}

//重新標記rx_tail位置

rxq->rx_tail = rx_id;

-------------------------------------------------

推薦閱讀

- 棧 vs 隊列

- Intel 82599網卡光模塊使用的坑

總結

以上是生活随笔為你收集整理的32位网卡驱动 2008_DPDK之网卡收包流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。