Cannot avoid context-switches on a process launched alone on a CPU

流过昼夜 提交于 2019-12-01 04:32:58

Today, I obtained more clues regarding my problem I realized that I had to investigate deeply what was happening in the Kernel scheduler. I found these two pages:

I enabled scheduler tracing while my application was running like that:

# sudo bash
# cd /sys/kernel/debug/tracing
# echo 1 > options/function-trace ; echo function_graph > current_tracer ; echo 1 > tracing_on ; echo 0 > tracing_max_latency ; taskset -c 7 [path-to-my-program]/TestCpuset ; echo 0 > tracing_on
# cat trace

As my program was launched on CPU 7 (taskset -c 7), I have to filter the "trace" output

# grep " 7)" trace

I can then search for transitions, from one process to another one:

# grep " 7)" trace | grep "=>"
 ...
 7)  TestCpu-4753  =>  kworker-5866 
 7)  kworker-5866  =>  TestCpu-4753 
 7)  TestCpu-4753  =>   watchdo-26  
 7)   watchdo-26   =>  TestCpu-4753 
 7)  TestCpu-4753  =>  kworker-5866 
 7)  kworker-5866  =>  TestCpu-4753 
 7)  TestCpu-4753  =>  kworker-5866 
 7)  kworker-5866  =>  TestCpu-4753 
 7)  TestCpu-4753  =>  kworker-5866 
 7)  kworker-5866  =>  TestCpu-4753 
 ...

Bingo! It seems that the context switches I am tracking are transitions to:

  • kworker
  • watchdog

I now have to find:

  • what are exactly these processes/threads? (it seems that they are handled by the kernel)
  • Can I avoid them to run on my dedicated CPUs?

For course, once again I would appreciate any help :-P

Potentially any syscall could involve context a switch. When you access paged out memory it may increase context switch count too. To reach 0 context switches you would need to force kernel to keep all the memory your program uses mapped to its address space, and you would need to be sure that none of syscalls you invoke entails a context switch. I believe it may be possible on kernels with RT patches, but probably hard to achieve on standard distro kernel.

For the sake of those finding this via google (like me), /sys/devices/virtual/workqueue/cpumask controls where the kernel may queue works queued with WORK_CPU_UNBOUND (Don't care which cpu). As of writing this answer, it's not set to the same mask as the one isolcpus manipulates by default.

Once I changed it to not include my isolated cpus, I saw a significantly smaller (but not zero) amount of context switches to my critical threads. I assume that the works that did run on my isolated cpus must have requested it specifically, such as by using schedule_on_each_cpu.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!