標籤:http tar art 問題 表 代碼
最近在升級netback, 進行測試過程中,發現vm全雙工系統壓力下,rx的pps波動很厲害,看到rx kthread雖然cpu affinity是0-7 (dom0 8vcpu), 但是經常跑到物理中斷的那個cpu上。
手動把rx kthread的cpu綁定到其他cpu上,rx pps上去了,並且穩定了,顯然rx 的pps波動就是因為cpu scheduling,被調度到不同的cpu導致。
有個疑問,為什麼cpu scheduling的時候,會把rx kthread調度到si%最高的cpu上呢,load balance的機制沒有發揮作用嘛?
先來看下代碼,rx kthread的實現是一個wait_event, 等包從網卡上收過來調用vif 的start_xmit,觸發wake_up。 也就是說包從網卡上來,並在那個cpu上觸發非強制中斷,然後wake_up 我們這個rx kthread起來幹活。
那麼是說rx kthread 跟wake_up的那個cpu有關?
xiantao大牛,發我看了下他們很早就發現的一個kvm上vm thread調度的問題,https://lkml.org/lkml/2010/4/11/108, 本質上應該是同一個問題。
簡單跟蹤了下代碼,try_to_wake_up的時候會調用sched_fair.c的select_task_rq_fair來挑選一個cpu,作為woken task的運行cpu。如果sched_feature.h裡面定義了
AFFINE_WAKEUPS 那麼want_affine=1,之後就出現一個affine_sd, 表示有親緣性的scheduling_domain, 然後調用wake_affine,裡面會對上一次啟動並執行cpu和當前wake_up
的cpu,進行一些load相關的比較,來選擇是基於prev_cpu還是wake_up cpu來選擇一個idle sibling (select_idle_sibling)
在我們的情境下,want_affine=1, wake_affine=1, select_idle_sibling(wake_up cpu),並且wake_up cpu也是idle,雖然非強制中斷很高,但是沒有其他的線程調度,一直都在idle上下文觸發非強制中斷。上述條件滿足下,try_to_wake_up得到的新cpu就是wake_up cpu。 極少情況下, wake_affine=0, 新的cpu就還是prev_cpu,等於沒有migration。
做過一個實驗,把sched_features.h 裡面的AFFINE_WAKEUPS =0, 那麼want_affine =0 ,就不會走到上面的邏輯,最後基本上就沒有migration,一直在prev_cpu上運行。
沒有了之前的波動,效能也上去了。