From dd6d746da219e03ac0ebd5991734381c7f474baa Mon Sep 17 00:00:00 2001 From: yunwei37 <1067852565@qq.com> Date: Fri, 2 Jun 2023 19:25:20 +0800 Subject: [PATCH] add the runqlat reasons --- README.md | 10 +++--- src/13-tcpconnlat/tcpconnlat.c | 1 - src/22-android/README.md | 4 ++- src/9-runqlat/README.md | 56 +++++++++++++++++++++++++++++++++- 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dc08444..f16d344 100644 --- a/README.md +++ b/README.md @@ -155,19 +155,19 @@ eunomia-bpf 由一个编译工具链和一个运行时库组成, 对比传统的 > - eunomia-bpf 项目 Github 地址: > - gitee 镜像: -## 让 chatGPT 来帮助我们 +## 让 ChatGPT 来帮助我们 -本教程借助 chatGPT 来学习编写 eBPF 程序,同时我们尝试教会 chatGPT 编写 eBPF 程序,大概步骤如下: +本教程借助 ChatGPT 来学习编写 eBPF 程序,同时我们尝试教会 ChatGPT 编写 eBPF 程序,大概步骤如下: 1. 告诉它基本的 eBPF 编程相关的常识 2. 告诉它一些案例:hello world,eBPF 程序的基本结构,如何使用 eBPF 程序进行追踪,并且让它开始编写教程 3. 手动调整教程,并纠正代码和文档中的错误 -4. 把修改后的代码再喂给 chatGPT,让它继续学习 -5. 尝试让 chatGPT 自动生成 eBPF 程序和对应的教程文档!例如 +4. 把修改后的代码再喂给 ChatGPT,让它继续学习 +5. 尝试让 ChatGPT 自动生成 eBPF 程序和对应的教程文档!例如 ![ebpf-chatgpt-signal](imgs/ebpf-chatgpt-signal.png) -完整的对话记录可以在这里找到: [chatGPT.md](chatGPT.md) +完整的对话记录可以在这里找到: [ChatGPT.md](ChatGPT.md) 我们也构建了一个命令行工具的 demo ,通过本教程的训练, 让它通过自然语言描述即可自动编写 eBPF 程序,追踪 Linux 系统:https://github.com/eunomia-bpf/GPTtrace diff --git a/src/13-tcpconnlat/tcpconnlat.c b/src/13-tcpconnlat/tcpconnlat.c index 8fa49a5..8c2ca9d 100644 --- a/src/13-tcpconnlat/tcpconnlat.c +++ b/src/13-tcpconnlat/tcpconnlat.c @@ -14,7 +14,6 @@ #include #include #include "tcpconnlat.skel.h" -// #include "trace_helpers.h" #define PERF_BUFFER_PAGES 16 #define PERF_POLL_TIMEOUT_MS 100 diff --git a/src/22-android/README.md b/src/22-android/README.md index 18220e6..c7d6a07 100644 --- a/src/22-android/README.md +++ b/src/22-android/README.md @@ -1,6 +1,6 @@ # 在 Andorid 上使用 eBPF 程序 -> 摘要:本文主要记录了笔者在 Android Studio Emulator 中测试高版本 Android Kernel 对基于 libbpf 的 CO-RE 技术支持程度的探索过程、结果和遇到的问题。 +> 本文主要记录了笔者在 Android Studio Emulator 中测试高版本 Android Kernel 对基于 libbpf 的 CO-RE 技术支持程度的探索过程、结果和遇到的问题。 > 测试采用的方式是在 Android Shell 环境下构建 Debian 环境,并基于此尝试构建 eunomia-bpf 工具链、运行其测试用例。 ## 背景 @@ -145,6 +145,8 @@ Error: BpfError("load and attach ebpf program failed") Android 系统 eBPF 工具的发展需要官方新特性的加入,目前看来通过 Android APP 直接使用 eBPF 工具需要的工作量较大,同时由于 eBPF 工具需要 root 权限,普通 Android 用户的使用会面临较多困难。 +如果希望学习更多关于 eBPF 的知识和实践,可以访问我们的教程代码仓库 以获取更多示例和完整的教程。 + ## 参考 [^Google]: diff --git a/src/9-runqlat/README.md b/src/9-runqlat/README.md index 46256ba..1f5db95 100755 --- a/src/9-runqlat/README.md +++ b/src/9-runqlat/README.md @@ -6,6 +6,55 @@ runqlat 是一个 eBPF 工具,用于分析 Linux 系统的调度性能。具 ## runqlat 原理 +本教程是 eBPF 入门开发实践系列的第九部分,主题是 "捕获进程调度延迟"。在此,我们将介绍一个名为 runqlat 的程序,其作用是以直方图的形式记录进程调度延迟。 + +Linux 操作系统使用进程来执行所有的系统和用户任务。这些进程可能被阻塞、杀死、运行,或者正在等待运行。处在后两种状态的进程数量决定了 CPU 运行队列的长度。 + +进程有几种可能的状态,如: + +- 可运行或正在运行 +- 可中断睡眠 +- 不可中断睡眠 +- 停止 +- 僵尸进程 + +等待资源或其他函数信号的进程会处在可中断或不可中断的睡眠状态:进程被置入睡眠状态,直到它需要的资源变得可用。然后,根据睡眠的类型,进程可以转移到可运行状态,或者保持睡眠。 + +即使进程拥有它需要的所有资源,它也不会立即开始运行。它会转移到可运行状态,与其他处在相同状态的进程一起排队。CPU可以在接下来的几秒钟或毫秒内执行这些进程。调度器为 CPU 排列进程,并决定下一个要执行的进程。 + +根据系统的硬件配置,这个可运行队列(称为 CPU 运行队列)的长度可以短也可以长。短的运行队列长度表示 CPU 没有被充分利用。另一方面,如果运行队列长,那么可能意味着 CPU 不够强大,无法执行所有的进程,或者 CPU 的核心数量不足。在理想的 CPU 利用率下,运行队列的长度将等于系统中的核心数量。 + +进程调度延迟,也被称为 "run queue latency",是衡量线程从变得可运行(例如,接收到中断,促使其处理更多工作)到实际在 CPU 上运行的时间。在 CPU 饱和的情况下,你可以想象线程必须等待其轮次。但在其他奇特的场景中,这也可能发生,而且在某些情况下,它可以通过调优减少,从而提高整个系统的性能。 + +我们将通过一个示例来阐述如何使用 runqlat 工具。这是一个负载非常重的系统: + +```shell +# runqlat +Tracing run queue latency... Hit Ctrl-C to end. +^C + usecs : count distribution + 0 -> 1 : 233 |*********** | + 2 -> 3 : 742 |************************************ | + 4 -> 7 : 203 |********** | + 8 -> 15 : 173 |******** | + 16 -> 31 : 24 |* | + 32 -> 63 : 0 | | + 64 -> 127 : 30 |* | + 128 -> 255 : 6 | | + 256 -> 511 : 3 | | + 512 -> 1023 : 5 | | + 1024 -> 2047 : 27 |* | + 2048 -> 4095 : 30 |* | + 4096 -> 8191 : 20 | | + 8192 -> 16383 : 29 |* | + 16384 -> 32767 : 809 |****************************************| + 32768 -> 65535 : 64 |*** | +``` + +在这个输出中,我们看到了一个双模分布,一个模在0到15微秒之间,另一个模在16到65毫秒之间。这些模式在分布(它仅仅是 "count" 列的视觉表示)中显示为尖峰。例如,读取一行:在追踪过程中,809个事件落入了16384到32767微秒的范围(16到32毫秒)。 + +在后续的教程中,我们将深入探讨如何利用 eBPF 对此类指标进行深度跟踪和分析,以更好地理解和优化系统性能。同时,我们也将学习更多关于 Linux 内核调度器、中断处理和 CPU 饱 + runqlat 的实现利用了 eBPF 程序,它通过内核跟踪点和函数探针来测量进程在运行队列中的时间。当进程被排队时,trace_enqueue 函数会在一个映射中记录时间戳。当进程被调度到 CPU 上运行时,handle_switch 函数会检索时间戳,并计算当前时间与排队时间之间的时间差。这个差值(或 delta)被用于更新进程的直方图,该直方图记录运行队列延迟的分布。该直方图可用于分析 Linux 内核的调度性能。 ## runqlat 代码实现 @@ -169,7 +218,7 @@ int BPF_PROG(handle_sched_switch, bool preempt, struct task_struct *prev, struct char LICENSE[] SEC("license") = "GPL"; ``` -首先,定义了一些常量和全局变量: +这其中定义了一些常量和全局变量,用于过滤对应的追踪目标: ```c #define MAX_ENTRIES 10240 @@ -384,6 +433,11 @@ comm = cpptools 128 -> 255 : 3 |********** | ``` +参考资料: + +- +- + ## 总结 runqlat 是一个 Linux 内核 BPF 程序,通过柱状图来总结调度程序运行队列延迟,显示任务等待运行在 CPU 上的时间长度。编译这个程序可以使用 ecc 工具,运行时可以使用 ecli 命令。