最近在升级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上运行。
没有了之前的波动,性能也上去了。
netback中kthread遇到的cpu affinity问题,布布扣,bubuko.com
netback中kthread遇到的cpu affinity问题
原文地址:http://blog.csdn.net/wanjia19870902/article/details/34074593