笔者做运维有时会遇到CPU占用率很高的场景。下面分享一下遇到类似问题的思路。
(一)top命令 首先登陆linux窗口,通过top命令可以看到CPU占用率的具体情况。如果是双核的话可以键入1。 看到的信息包括: CPU占用率高的线程/进程。 用户态占用高还是内核态占用高;硬中断高还是软中断高。
(二)/proc/xxx/sched 通过第一步,找到占用率高的线程后,通过如下命令查看是该进程/线程主动schedule还是被动schedule cat /proc/xxx/sched > sched.log; sleep; cat /proc/xxx/sched >> sched.log
(三)ftrace 通过ftrace可以看到进程的调度轨迹,也就是各个状态的切换。
(四)sysrq_trigger捕捉进程调度快照 echo t > /proc/sysrq-trigger
(五)profile和perf 这两个工具是性能分析的倚天屠龙,其中perf可以抓到指令级别的时间消耗。
笔者遇到的是某一个内核线程CPU占用高,比如khubd, events。通过各种方法抓取效果甚微,通过perf和profile确认是schedule函数占用率高,perf没有完整的调试工具,所以当时没有抓到指令级别的时间消耗。通过打印信息确认schedule函数发现待休眠的线程有信号未处理导致。因为内核线程休眠前发现signal_suspend之后会主动把线程的state修改为RUNNING导致线程无法休眠。 而内核线程收到的信号是别的线程某种条件下发force_sig_info给内核线程。
而该信号是我们自己写的代码在某种情况下误发给内核线程的。
参考文章
Linux 线程占用CPU过高定位分析 https://www.cnblogs.com/Forever-Kenlen-Ja/p/8618102.html
进程kswapd0与events/0消耗大量CPU的问题 https://blog.csdn.net/qq_31666147/article/details/52956064?utm_source=blogxgwz5
linux进程调度函数浅析(基于3.16-rc4) https://www.cnblogs.com/liangning/p/3885933.html
交叉编译环境下的perf使用 https://www.veryarm.com/44784.html
linux perf - 性能测试和优化工具 https://www.cnblogs.com/hushaojun/p/4848269.html
《Systems Performance》阅读笔记及收获 https://www.cnblogs.com/arnoldlu/p/7998225.html
linux内核线程对信号的处理过程 http://www.51testing.com/html/63/524463-819036.html
关于sys CPU usage 100%问题的分析 https://blogs.oracle.com/database4cn/sys-cpu-usage-100
perf官网 https://perf.wiki.kernel.org/index.php/Tutorial
Analyzing performance with perf annotate https://developer.ibm.com/tutorials/l-analyzing-performance-perf-annotate-trs/
Perf -- Linux下的系统性能调优工具,第 1 部分 https://www.ibm.com/developerworks/cn/linux/l-cn-perf1/ https://www.ibm.com/developerworks/cn/linux/l-cn-perf2/
Iowait的成因、对系统影响及对策 https://cloud.tencent.com/developer/article/1071025
动态链接库地址重定位 https://blog.csdn.net/imyangjianwei/article/details/84700705
理解 %IOWAIT (%WIO) https://blog.csdn.net/lurryjing1987/article/details/82591501