netback的tasklet調度問題及網卡丟包的簡單分析

最近在萬兆網卡上測試,出現了之前千兆網卡沒有出現的一個現象,tasklet版本的netback下,vm進行發包測試,發現vif的interrupt默認綁定在cpu0上,但是vm發包運行時發現host上面cpu1, cpu2的ksoftirqd很高。


從之前的理解上來說,包從netfront出來通過eventchannel notify觸發vif的irq處理函數,然後tasklet_schedule調用tx_action,通過一系列處理流程把包發給網卡。所以vif的interrupt綁在哪個cpu上,發包的時候,那個cpu的si%高才對。


仔細查看tasklet的代碼發現,除了interrupt處理函數裏面會調用tasklet_schedule之外,還有一個地方會調用,就是netif_idx_release, 這個是配合grant map使用的一個回調函數。當skb從網卡發出之後,kfree_skb時候,會調用page註冊的一個回調,告訴netback,這個skb發送完成了,你可以給netfront 發送response了,然後順便tasklet_schedule一把。


所以從這裏,就不難看出,cpu1, cpu2上softirq高,tasklet也高, 是因爲網卡中斷都在cpu1, cpu2上。


開始我有點犯傻,覺得tx的時候,怎麼會觸發網卡中斷呢,不應該是rx的時候纔有的。後來看了igb的驅動,才發現真的傻。


網卡發完包,得把skb回收啊,這個時候,就是通過觸發之前request_irq的函數來完成的,收包發包都走這一個函數。


就拿線上萬兆網卡ixgbe來說


中斷處理函數是ixgbe_msix_clean_many,裏面調用napi_schedule, 走到ixgbe_poll。這個函數就是我們上面提到的收包發包都在這個裏面處理的。


它會先調用ixgbe_clean_tx_irq, 對之前tx發送的包進行回收處理(ixgbe_unmap_and_free_tx_resource),接着調用ixgbe_clean_rx_irq


這個裏面會rx_ring裏面的rx_buffer_info包括的skb,調用協議棧的收包函數,扔給上層處理,ixgbe_receive_skb->napi_gro_receive->netif_receive_skb


這個rx_ring的count在網卡驅動加載時默認是1024,我們設置了最大上限4096個,是驅動裏面每次接收完一批包的時候,就會ixgbe_alloc_rx_buffers 分配一批新的skb和page

pci_dma映射好給硬件去收包


這裏第一個tasklet調度到cpu1, cpu2的問題就能解釋, vm發包觸發了網卡的cpu1, cpu2上的中斷,一直到軟中斷,kfree_skb,觸發idx_release,接着tasklet_schedule, 然後tx_action就一直在這兩個cpu上,然後vif發包下來觸發中斷的時候,調用maybe_schedule_tx_action,裏面會判斷當前pending是否小於max/2,如果小於纔去調用tasklet_schedule,這樣即使被調用,可能tasklet已經在運行了。爲什麼之前千兆網絡沒怎麼出現,可能是因爲idx_release被調用的變快了吧,沒去確認,這已經不重要了。


剛好還有一個網卡丟包的問題,跟網卡驅動有點關係,有個測試發現物理口收了14w的包,丟了45w的包,ethtool -S 看到的話是rx_fifo_errors, 這大概就表明因爲沒有buffer導致的。剛剛上面也講到rx_buffer,是在處理完一批請求之後再去分配一批新的buffer,總共就4096個。如果cpu處理變慢,那麼外面大壓力發過來的情況下,就會有很多丟包,跟cpu的處理能力有關。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章