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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网卡驱动收发包过程图解

發布時間:2023/12/20 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网卡驱动收发包过程图解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

網卡

網卡工作在物理層和數據鏈路層,主要由PHY/MAC芯片、Tx/Rx FIFO、DMA等組成,其中網線通過變壓器接PHY芯片、PHY芯片通過MII接MAC芯片、MAC芯片接PCI總線

PHY芯片主要負責:CSMA/CD、模數轉換、編解碼、串并轉換

MAC芯片主要負責:

1. 比特流和幀的轉換:7字節的前導碼Preamble和1字節的幀首定界符SFD

2. CRC校驗

3. Packet Filtering:L2 Filtering、VLAN Filtering、Manageability / Host Filtering

Intel的千兆網卡以82575/82576為代表、萬兆網卡以82598/82599為代表

收發包過程圖

ixgbe_adapter包含ixgbe_q_vector數組(一個ixgbe_q_vector對應一個中斷),ixgbe_q_vector包含napi_struct

硬中斷函數把napi_struct加入CPU的poll_list,軟中斷函數net_rx_action()遍歷poll_list,執行poll函數


發包過程


1、網卡驅動創建tx descriptor ring(一致性DMA內存),將tx descriptor ring的總線地址寫入網卡寄存器TDBA

2、協議棧通過dev_queue_xmit()將sk_buff下送網卡驅動

3、網卡驅動將sk_buff放入tx descriptor ring,更新TDT

4、DMA感知到TDT的改變后,找到tx descriptor ring中下一個將要使用的descriptor

5、DMA通過PCI總線將descriptor的數據緩存區復制到Tx FIFO

6、復制完后,通過MAC芯片將數據包發送出去

7、發送完后,網卡更新TDH,啟動硬中斷通知CPU釋放數據緩存區中的數據包

Tx Ring Buffer

收包過程

1、網卡驅動創建rx descriptor ring(一致性DMA內存),將rx descriptor ring的總線地址寫入網卡寄存器RDBA

2、網卡驅動為每個descriptor分配sk_buff和數據緩存區,流式DMA映射數據緩存區,將數據緩存區的總線地址保存到descriptor

3、網卡接收數據包,將數據包寫入Rx FIFO

4、DMA找到rx descriptor ring中下一個將要使用的descriptor

5、整個數據包寫入Rx FIFO后,DMA通過PCI總線將Rx FIFO中的數據包復制到descriptor的數據緩存區

6、復制完后,網卡啟動硬中斷通知CPU數據緩存區中已經有新的數據包了,CPU執行硬中斷函數:

  • NAPI(以e1000網卡為例):e1000_intr() -> __napi_schedule() -> __raise_softirq_irqoff(NET_RX_SOFTIRQ)
  • 非NAPI(以dm9000網卡為例):dm9000_interrupt() -> dm9000_rx() -> netif_rx() -> napi_schedule() -> __napi_schedule() -> __raise_softirq_irqoff(NET_RX_SOFTIRQ)

7、ksoftirqd執行軟中斷函數net_rx_action():

  • NAPI(以e1000網卡為例):net_rx_action() -> e1000_clean() -> e1000_clean_rx_irq() -> e1000_receive_skb() -> netif_receive_skb()
  • 非NAPI(以dm9000網卡為例):net_rx_action() -> process_backlog() -> netif_receive_skb()

8、網卡驅動通過netif_receive_skb()將sk_buff上送協議棧

Rx Ring Buffer

軟件(SW)向從next_to_use開始的N個descriptor補充sk_buff,next_to_use += N,tail = next_to_use - 1(設置網卡寄存器RDT)

硬件(HW)向從head開始的M個descriptor的sk_buff復制數據包并設置DD,head += M

SW將從next_to_clean的開始的L個sk_buff移出Rx Ring Buffer交給協議棧,next_to_clean += L,向從next_to_use開始的L個descriptor補充sk_buff,next_to_use += L,tail = next_to_use - 1

注意:每次補充完sk_buff以后,tail、next_to_use、next_to_clean三者都是緊挨著的


中斷上下部


do_IRQ()是CPU處理硬中斷的總入口,在do_IRQ()中調用硬中斷函數

netif_rx()

在netif_rx()中把skb加入CPU的softnet_data

RSS + FDIR

FDIR(Flow Director)的優先級高于RSS(Receive Side Scaling)

RSS通過計算包的五元組(sip、sport、dip、dport、protocol)的hash并取余,得到隊列的index,然后將包放入這個隊列,實現了數據包在各個隊列之間的負載均衡,不過RSS不能保證回包也落在同一個隊列上

對稱hash(sip/sport和dip/dport交換后hash不變)可以部分解決該問題,但是對于一些需要做NAT的設備(比如負載均衡)就失效了,FDIR可以完全解決該問題,參見https://tech.meituan.com/MGW.html

總結

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

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