Skip to content

Commit

Permalink
Merge pull request #758 from vvzxy/develop
Browse files Browse the repository at this point in the history
cpu_watcher:添加readme文档
  • Loading branch information
chenamy2017 authored Apr 11, 2024
2 parents f6904da + 32660db commit e17f775
Showing 1 changed file with 225 additions and 0 deletions.
225 changes: 225 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/README.md
Original file line number Diff line number Diff line change
@@ -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负责人:**[email protected] [email protected] [email protected]

0 comments on commit e17f775

Please sign in to comment.