diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/README.md b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/README.md new file mode 100644 index 000000000..b4de8b930 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/README.md @@ -0,0 +1,225 @@ +# cpu_watcher:动态CPU指标实时监测 + +## 一、项目简介 + +​ `CPU_Watcher`是一项基于`eBPF(Extended Berkeley Packet Filter)`技术的项目,旨在实现对`CPU`各项指标的实时动态监测和分析,可以清晰且直观的了解CPU资源利用率以及事件的发生的速率。 + +​ 本工具使用ebpf工具进行实现,`eBPF`是`Linux`内核中的一种强大的工具,它允许在内核空间执行小型程序,用于在运行时过滤、转发和监控系统事件。 + +​ `CPU_Watcher`利用`eBPF`的这一特性,通过在内核空间执行精简的程序来捕获`CPU`相关的事件和指标,从而实现对`CPU`性能的实时监测和分析。 + +## 二、使用方法 + +### 1.使用环境 + +- OS:Ubuntu 22.04 +- kernel:Linux 6.2 + +### 2.编译运行 + +```shell +make 编译 +sudo ./cpu_watcher -[options] 运行 +make clean 清除生成文件 +``` + +## 三、功能介绍 + +​ `cpu_watcher`是一个用于监视系统 CPU 使用情况的工具,它可以帮助用户了解系统在不同负载下的性能表现,并提供详细的统计数据。该工具分为以下几个部分,通过不同的参数控制相关的`ebpf`捕获程序是否加载到内核中: + +| 参数 | 描述 | +| :----------------: | :----------------------------------------: | +| -s :SAR | 实时采集SAR的各项指标,每秒输出一次 | +| -p:preempt_time | 实时采集当前系统的每次抢占调度详细信息 | +| -d:schedule_delay | 实时采集当前系统的调度时延 | +| -S:syscall_delay | 实时采集当前系统调用时间 | +| -m:mq_delay | 实时采集当前消息队列通信时延 | +| -c:cs_delay | 实时对内核函数schedule()的执行时长进行测试 | + +### 1.SAR 统计功能(每秒输出一次): + +#### 输出效果: + +``` + time proc/s cswch/s runqlen irqTime/us softirq/us idle/ms kthread/us sysc/ms utime/ms sys/ms +16:18:03 29 1216 1 1277 19394 1087 2908 662 747 665 +16:18:04 43 2036 2 1262 24823 1432 3981 72 171 76 +16:18:05 0 1371 2 4927 16949 1152 2489 538 636 541 +16:18:06 11 2569 4 10900 9085 518 2967 941 1121 944 +16:18:07 3 5166 4 9929 15864 469 10778 482 1020 493 +16:18:08 30 2426 2 2436 17877 1435 5086 90 262 96 +16:18:09 43 1257 1 351 20457 1713 3040 8 40 11 +16:18:10 0 813 1 20071 30563 1727 117472 41 0 159 +16:18:11 0 751 1 748 14532 1855 3935 16 50 20 +16:18:12 0 1118 1 1115 20750 1733 1956 1 50 3 +16:18:13 29 1083 1 286 18081 1698 3861 50 10 54 +16:18:14 43 1032 1 577 19513 1704 3919 26 10 30 +``` + +对上述参数的解释: + +- `proc/s`: 每秒创建的进程数,此数值是通过fork数来统计的。 +- `cswch/s`: 每秒上下文切换数。 +- `runqlen`:此时CPU的运行队列的长度。 +- `irqTime/us`:CPU响应`irq`中断所占用的时间,是所有CPU时间的叠加。 +- `softirq/us`: CPU执行`softirq`所占用的时间,是所有CPU时间的叠加。 +- `idle/ms`: CPU处于空闲状态的时间,是所有CPU时间的叠加。 +- `kthread/us`: CPU执行内核线程所占用的时间,是所有CPU的叠加。不包括IDLE-0进程,因为此进程只执行空闲指令使CPU闲置。 +- `sysc/ms`: CPU执行用户程序系统调用(`syscall`)所占用的时间,是所有CPU的叠加。 +- ` utime/ms`:CPU执行普通用户进程时,花在用户态的时间,是所有CPU的叠加。 + +### **2.统计抢占调度时间:** + +​ 统计系统中发生抢占调度的情况,包括抢占进程的`pid`与进程名,以及被强占进程的`pid`,和本次抢占时间,单位纳秒。 + +#### 输出效果: + +``` +COMM prev_pid next_pid duration_ns +node 14221 2589 3014 +kworker/u256:1 15144 13516 1277 +node 14221 2589 3115 +kworker/u256:1 15144 13516 1125 +kworker/u256:1 15144 13516 974 +node 14221 2589 2560 +kworker/u256:1 15144 13516 1132 +node 14221 2589 2717 +kworker/u256:1 15144 13516 1206 +kworker/u256:1 15144 13516 1131 +node 14221 2589 3355 +``` + +### 3.**统计调度延迟:** + +​ 分析系统中进程调度的延迟情况,提供相关统计数据,输出包括当前系统的最大调度延迟、最小调度延迟、平均调度延迟。 + +#### 输出效果: + +``` + TIME avg_delay/μs max_delay/μs min_delay/μs +17:31:28 35.005000 97.663000 9.399000 +17:31:29 326.518000 12618.465000 7.994000 +17:31:30 455.837000 217053.545000 6.462000 +17:31:31 422.582000 217053.545000 6.462000 +17:31:32 382.627000 217053.545000 6.462000 +17:31:33 360.499000 217053.545000 6.462000 +17:31:34 364.805000 217053.545000 6.462000 +17:31:35 362.039000 217053.545000 6.462000 +17:31:36 373.751000 217053.545000 6.462000 +``` + +### 4.**统计系统调用响应时间:** + +​ 记录系统调用的响应时间,帮助用户评估系统对外部请求的处理效率, 其输出包括发起本次系统调用的进程的进程名、pid、系统调用号以及响应时间。 + +#### 输出效果: + +``` +Time Pid comm syscall_id delay/us +21:28:07 276073 cpu_watcher 1 21 +21:28:07 2579 node 0 7 +21:28:07 276073 cpu_watcher 4 8 +21:28:07 2579 node 232 6 +21:28:07 2579 node 0 6 +21:28:07 276073 cpu_watcher 1 22 +21:28:07 276073 cpu_watcher 4 8 +``` + +### 5.**统计消息队列延迟:** + +​ 统计进程间通过消息队列通信时,消息块从发送到接收的延迟情况,以便用户了解系统中进程间通信的效率和延迟,其输出内容包括发消息动作(mq_send)的延迟、接收消息动作(mq_receive)的延迟、消息块从发送到接收过程的延迟。 + +#### 输出效果: + +```c + Time Mqdes SND_PID RCV_PID SND_Delay/ms RCV_Delay/ms Delay/ms +21:40:36 3 281101 281167 0.02 0.02 2161.58542 +21:40:46 3 281432 281493 0.02 0.03 1373.68176 +21:40:52 3 281680 281741 0.03 0.05 1494.31408 +21:40:58 3 281909 281945 0.03 0.02 1434.06373 +21:41:01 3 282019 282088 0.03 0.02 1401.26321 +``` + +原理介绍: + +[lmp/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/docs/mq_delay功能介绍.md at develop · albertxu216/lmp (github.com)](https://github.com/albertxu216/lmp/blob/develop/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/docs/mq_delay功能介绍.md) + +### 6.对内核函数schedule()的执行时长进行测试 + +​ 统计每次调度的执行时间,可以输出本次调度的时间,单位为微秒,并用直方图展示汇总结果: + +#### 输出效果: + +``` +t1:4817139183 t2:4817139248 delay:65 +t1:4817139255 t2:4817139319 delay:64 +t1:4817139454 t2:4817139505 delay:51 +t1:4817139512 t2:4817139557 delay:45 +t1:4817139675 t2:4817139735 delay:60 +t1:4817139742 t2:4817139800 delay:58 +t1:4817139936 t2:4817139998 delay:62 +t1:4817140005 t2:4817140065 delay:60 +t1:4817140488 t2:4817140552 delay:64 +t1:4817140559 t2:4817140621 delay:62 +t1:4817140816 t2:4817140878 delay:62 +t1:4817141241 t2:4817141303 delay:62 +``` + +```c +Time : 21:46:45 +cs_delay Count Distribution +0 => 1 585 | +2 => 3 856 | +4 => 7 2271 |** +8 => 15 5792 |***** +16 => 31 8641 |******** +32 => 63 9762 |********* +64 => 127 2041 |** +128 => 255 2158 |** +256 => 511 2075 |** +512 => 1023 751 | +1024 => 2047 301 | +2048 => 4095 112 | +4096 => 8191 36 | +8192 => 16383 0 | +16384 => 32767 0 | +32768 => 65535 0 | +65536 => 131071 0 | +131072 => 262143 0 | +262144 => 524287 0 | +524288 => 1048575 0 | +per_len = 1000 +``` + + + +## 四、实现方式 + +### 1.使用kprobe捕获内核函数的参数 + +​ 使用kprobe、kretprobe捕获挂载的内核函数的参数,从参数中提取有效的数据。比如从finish_task_switch.isra.0内核函数的参数中拿取关于prev进程的相关信息。 + +### 2.使用内核提供的tracepoint捕获特定时间 + +​ 使用tracepoint捕获特定状态的开始和结束,计算持续时间。比如softirq运行时间就是通过内核提供的tracepoint计算的。 + +### 3.获取内核全局变量 + +​ 获取内核全局变量,直接从内核全局变量读取信息。如proc/s就是通过直接读取total_forks内核全局变量来计算每秒产生进程数的。 + + + +## 五、未来展望 + +目前`cpu_watcher`工具的总体框架已经完成,工具所能满足的功能已覆盖CPU所涉及的大部分性能指标。下一阶段,本工具将从以下几个方向进行开发和优化: + +* 完善工具可视化; +* 功能模块化; +* 更细粒度的提取CPU相关指标; +* 完善工具,使其适配更多场景; + + + +如果你也对cpu_watcher或ebpf感兴趣,欢迎加入我们一起开发cpu_watcher工具,希望我们可以共同成长。 + +**cpu_watcher负责人:**albert_xuu@163.com zhangxy1016304@163.com zhangziheng0525@163.com \ No newline at end of file