成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux網絡包從中斷到接收的一生

系統 Linux
如果在虛擬化環境下,VMM配置GIC ITS (Interrupt Translation Service) ,建立物理中斷與虛擬中斷的映射完成中斷虛擬化使得網卡能直接向VM發出中斷,同時通過IO虛擬化,網卡通過IOMMU將packet直接寫入虛擬機內核的rx_ring

 [[333072]]

 

Linux網絡包從中斷到接收的一生

 

linux

既然要講,那就把一個包的整個包生都說了算了

觸發中斷

  • 在非虛擬化環境下,網卡通過DMA將packet寫入內核的rx_ring環形隊列緩沖區,并觸發中斷。
  • 如果在虛擬化環境下,VMM配置GIC ITS (Interrupt Translation Service) ,建立物理中斷與虛擬中斷的映射完成中斷虛擬化使得網卡能直接向VM發出中斷,同時通過IO虛擬化,網卡通過IOMMU將packet直接寫入虛擬機內核的rx_ring

Top Half

  • CPU在收到中斷之后,調用網卡ISR也就是所謂的中斷handler
  • 分配sk_buf并入input_pkt_queue(如果隊列已滿則丟棄)
  • 發出一個軟中斷NET_RX_SOFTIRQ,軟中斷可以被調度例如通過tasklet

Bottom Half

  • sk_buf從input_pkt_queue傳入process_queue,根據協議類型調用網絡層協議的handler
  • ip_rcv執行包頭檢查,ip_router_input()進行路由,決定本機/轉發/丟棄
  • tcp_v4_rcv執行包頭檢查,tcp_v4_lookup查詢對應的socket和connection,如果正常,tcp_prequeue將skb放進socket接收隊列
  • socket隨即喚醒所在的進程

 

Linux網絡包從中斷到接收的一生

 

kqueue

因為epoll沒有論文,就說說kqueue是怎么做的吧,kqueue會根據socket綁定的knote鏈表(每個監聽的kqueue都可能創建一個knote),將knote通過反向指針獲得kqueue,將knote加入kqueue的就緒隊列末尾。如果此時恰好有進程正在監聽的話,將會喚醒進程,kqueue會被掃描,并從就緒隊列處獲得所有的event,從而了解已經就緒的所有socket。

  • 喚醒的進程調用socket recv系統調用,如果是TCP則調用tcp_recvmsg從sk_buffer拷貝數據

Batch

  1. netif_receive_skb_list() 

Linux的NAPI還會繼續延遲軟中斷的處理,等待其積累足夠的skb后進行輪詢,一次性處理所有的skb。

SKB

skb并不是直接存儲報文,而是存儲指針,指針只需要移動,就能完成解包,而本身的報文并不需要修改。上一層的協議棧會在處理當前層的同時設置好下一層的頭指針,并且移動data指針。與此同時,skb本身是雙向鏈表實現的隊列。qlen為鏈表元素長度,lock為添加元素時的鎖。

 

Linux網絡包從中斷到接收的一生

 

skb結構

談到指針的用法,這里舉個做OS lab時印象深刻的奇淫巧技,也是C的指針變態的地方

  1. #define list_entry(ptr, type, field) \ 
  2.     container_of(ptr, type, field) 
  3. #define container_of(ptr, type, field) \ 
  4.     ((type *)((void *)(ptr) - (u64)(&(((type *)(0))->field)))) 

(u64)(&(((type *)(0))->field))))指的是field在結構體type中的偏移量,通過減去這個偏移量我們就能找出某個對象所在上級type對象的地址,也就是container。

一般來說,我們都會使用下面這樣的方式,讓鏈表節點去包裹數據。

  1. struct page_list_node { 
  2.         struct page p; 
  3.     struct list_node *prev; 
  4.     struct list_node *next
  5. }; 

但是,通過指針操作,卻可以讓數據去包裹鏈表節點

  1. struct list_head { 
  2.     struct list_head *prev; 
  3.     struct list_head *next
  4. }; 
  5.  
  6. struct page{ 
  7.     struct list_head      list_node; 

在僅僅知道鏈表節點的情況下,借助成員偏移量即可知道容器對象的位置并取出

  1. list_entry(somenode,struct page,list_node); 

list_head本身可以存在于任何對象上,而他們的entry卻能根據參數而指向不同的類型,感覺有點泛型的味道了。

內容來自SJTU,IPADS OS-16-Network

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2021-08-06 22:43:54

中斷架構傳遞

2015-04-23 08:51:53

2018-01-18 09:05:05

存儲數據包分層

2015-08-03 09:33:21

PH程序員一生

2016-08-24 11:13:30

2023-01-10 08:20:55

RocketMQ消息源碼

2017-03-28 13:25:14

Linux網絡數據包

2020-10-29 15:05:31

Linux網絡包代碼

2012-12-04 10:08:16

2018-01-05 12:42:01

Lisa電腦蘋果Mac

2020-11-29 17:08:50

程序員IT

2015-03-24 13:39:08

IE

2025-05-19 08:43:00

2021-09-28 08:05:56

黑客網絡安全網絡攻擊

2014-10-11 11:35:49

2021-12-28 18:23:49

Java指令

2010-01-07 09:32:19

2017-04-11 17:22:57

編程程序員語言

2012-04-16 09:24:49

程序員

2016-01-25 13:22:45

SparkSparkSQL數據分析
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久久久久久久免费看 | 久久国产精品色av免费观看 | 色久在线 | 中文字幕在线观看一区 | 中文字幕免费在线 | 欧美成人一区二区三区 | 中文字幕在线视频精品 | 亚洲播放 | 九九热精品视频 | 成人免费一区二区三区视频网站 | 久久久久99 | 成人免费在线视频 | www日本在线播放 | 国产精品日本一区二区在线播放 | 国产成人精品一区二区三区 | 久草热线 | 美女二区 | 久久精品欧美一区二区三区麻豆 | 激情婷婷| 在线观看视频你懂得 | 欧美日韩精品在线免费观看 | 极品电影院 | 一区二区成人 | 亚洲成人av在线播放 | 精品免费国产一区二区三区 | 久久人操| 亚洲视频中文字幕 | 精品不卡 | 中文字幕一区二区三区在线乱码 | 精品国产乱码久久久久久闺蜜 | 欧美性猛交一区二区三区精品 | 99免费在线观看 | 黄色91在线 | 成人在线视频免费观看 | 黄网站免费入口 | 欧美黄色免费网站 | 91精品久久久久久久久中文字幕 | 99久热在线精品视频观看 | 成人亚洲在线 | 综合婷婷 | 亚洲欧美激情视频 |