kernel/events 性能事件(Perf Events)机制与原理详解
源码路径 :rk3588/kernel-6.1/kernel/events/内核版本 :Linux 6.1(RK3588 平台)平台 :RK3588(4×Cortex-A76 + 4×Cortex-A55 big.LITTLE,ARM64)
该目录实现 Linux 内核 Perf Events(性能事件) 子系统的核心框架,为 perf、ftrace、BPF、KVM PMU 等提供统一的性能计数、采样、追踪基础设施。用户态通过 perf_event_open(2) 创建事件,内核将采样数据写入 mmap 环形缓冲区 ,供 perf record 等工具消费。
目录
一、源码目录结构 1.1 编译依赖(Makefile) 1 2 3 4 5 obj-y := core.o ring_buffer.o callchain.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_HW_BREAKPOINT_KUNIT_TEST) += hw_breakpoint_test.o obj-$(CONFIG_UPROBES) += uprobes.o
配置项
说明
CONFIG_PERF_EVENTS
启用 perf 子系统(kernel/Makefile 中 obj-$(CONFIG_PERF_EVENTS) += events/)
CONFIG_HAVE_HW_BREAKPOINT
硬件断点支持(ARM64 在 PERF_EVENTS 下 select)
CONFIG_UPROBES
用户态探针(trace Kconfig 中 select)
CONFIG_UPROBE_EVENTS
将 uprobes 注册为 perf PMU
CONFIG_HW_BREAKPOINT_KUNIT_TEST
硬件断点 KUnit 单元测试
1.2 源文件
文件
行数
功能
core.c
~13825
perf 核心:syscall、PMU 注册、上下文调度、采样、mmap、BPF 集成
ring_buffer.c
~972
mmap 环形缓冲区读写、AUX 区域、内存屏障同步
callchain.c
~253
采样调用栈收集与缓冲区管理
hw_breakpoint.c
~1051
硬件断点 slot 约束、perf_event 集成
uprobes.c
~2360
用户态断点探针、XOL 单步执行
hw_breakpoint_test.c
~333
KUnit 硬件断点测试(非生产路径)
internal.h
~247
环形缓冲区内部 API、递归上下文保护
相关头文件 :
文件
功能
include/linux/perf_event.h
公共 API:struct pmu、struct perf_event、内核/用户接口
include/linux/hw_breakpoint.h
硬件断点 API
include/linux/uprobes.h
uprobes 公共接口
架构/驱动层(RK3588 实际硬件 PMU) :
文件
功能
drivers/perf/arm_pmu.c
ARM 通用 PMU 驱动框架
drivers/perf/arm_pmu_platform.c
平台 PMU 注册(含 Cortex-A76/A55)
arch/arm64/kernel/perf_event.c
ARM64 PMU 架构实现
arch/arm64/kvm/pmu-emul.c
KVM guest PMU 模拟
二、整体架构 2.1 分层模型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ┌─────────────────────────────────────────────────────────────┐ │ 用户态:perf / trace-cmd / BPF / gdb │ │ perf_event_open(2) + mmap + poll/read │ └───────────────────────────┬─────────────────────────────────┘ │ ┌───────────────────────────▼─────────────────────────────────┐ │ kernel/events/core.c │ │ 事件分配 · 上下文调度 · 采样输出 · 权限控制 · sysfs │ └───────────────────────────┬─────────────────────────────────┘ │ ┌──────────────────┼──────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ software │ │ tracepoint │ │ armv8_pmuv3 │ │ PMU │ │ / kprobe │ │ (CPU PMU) │ │ │ │ / uprobe │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └──────────────────┴──────────────────┘ │ ┌───────────────────────────▼─────────────────────────────────┐ │ kernel/events/ring_buffer.c │ │ perf_buffer 环形缓冲区 → mmap 映射到用户态 │ └─────────────────────────────────────────────────────────────┘
2.2 事件类型(type 字段)
type
PMU 名称
说明
PERF_TYPE_HARDWARE
armv8_pmuv3 等
CPU 硬件计数器(cycles、cache miss 等)
PERF_TYPE_SOFTWARE
software
软件事件(page fault、context switch 等)
PERF_TYPE_TRACEPOINT
tracepoint
内核 tracepoint
动态分配
kprobe / uprobe
内核/用户态动态探针
自定义
各 SoC uncore PMU
DDR、CCI 等(RK3588 通用 ARM PMU 为主)
2.3 与其他子系统的关系
子系统
关系
kernel/trace/
tracepoint PMU 依赖 perf 框架;ftrace 与 perf 共享 tracepoint
kernel/bpf/
BPF 程序可 attach 到 perf event 作为 overflow handler
kernel/cgroup/
CONFIG_CGROUP_PERF 支持按 cgroup 过滤事件
kernel/entry/
采样时获取 pt_regs;uprobe 通过 TIF_UPROBE 在返回用户态时处理
三、核心数据结构 3.1 struct pmu — 性能监控单元抽象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 struct pmu { struct list_head entry ; const char *name; int type; int capabilities; int (*event_init)(struct perf_event *event); int (*add)(struct perf_event *event, int flags); void (*del)(struct perf_event *event, int flags); void (*start)(struct perf_event *event, int flags); void (*stop)(struct perf_event *event, int flags); void (*read)(struct perf_event *event); struct perf_cpu_context __percpu *pmu_cpu_context ; };
每个 PMU(software、tracepoint、armv8_pmuv3 等)通过 perf_pmu_register() 注册到全局 PMU 链表。
3.2 struct perf_event — 单个性能事件 1 2 3 4 5 6 7 8 9 10 11 struct perf_event { struct pmu *pmu ; struct perf_event_attr attr ; struct perf_event_context *ctx ; struct perf_event *group_leader ; struct list_head event_entry ; struct hw_perf_event hw ; struct perf_buffer *rb ; };
struct perf_event_attr 定义采样类型(sample_type)、采样周期(sample_period / sample_freq)、过滤条件(exclude_kernel、exclude_user)等。
3.3 struct perf_event_context — 事件上下文 1 2 3 4 5 6 7 8 9 10 struct perf_event_context { struct pmu *pmu ; struct task_struct *task ; struct list_head event_list ; struct mutex mutex ; raw_spinlock_t lock; int nr_events; int nr_active; };
task context :绑定到特定进程/线程的事件集合
cpu context :绑定到特定 CPU 的事件集合(task == NULL)
3.4 struct perf_cpu_context — 每 CPU 上下文 1 2 3 4 5 6 struct perf_cpu_context { struct perf_event_context ctx ; struct perf_event_context *task_ctx ; struct pmu *pmu ; };
每个 PMU 在每个 CPU 上有一个 perf_cpu_context,管理该 PMU 在该 CPU 上的所有事件调度。
3.5 struct perf_buffer — 环形缓冲区(internal.h) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 struct perf_buffer { refcount_t refcount; int nr_pages; int overwrite; local_t head; local_t lost; long watermark; unsigned int nest; struct perf_event_mmap_page *user_page ; void *data_pages[]; long aux_head; int aux_nr_pages; void **aux_pages; };
四、PMU 抽象与注册 4.1 初始化顺序(perf_event_init) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void __init perf_event_init (void ) { idr_init(&pmu_idr); perf_event_init_all_cpus(); init_srcu_struct(&pmus_srcu); perf_pmu_register(&perf_swevent, "software" , PERF_TYPE_SOFTWARE); perf_pmu_register(&perf_cpu_clock, NULL , -1 ); perf_pmu_register(&perf_task_clock, NULL , -1 ); perf_tp_register(); perf_event_init_cpu(smp_processor_id()); init_hw_breakpoint(); perf_event_cache = KMEM_CACHE(perf_event, SLAB_PANIC); }
4.2 perf_pmu_register 流程 1 2 3 4 5 6 perf_pmu_register(pmu, name, type) → 分配 pmu_disable_count (percpu) → idr_alloc 分配 type ID(非 SOFTWARE 类型) → 分配/关联 perf_cpu_context (percpu) → 加入全局 pmus 链表 → 注册 sysfs 设备(device_initcall 阶段)
4.3 已注册 PMU 一览
PMU
type
注册位置
software
PERF_TYPE_SOFTWARE
core.c
cpu_clock / task_clock
-1(无 type)
core.c
tracepoint
PERF_TYPE_TRACEPOINT
core.c
kprobe
动态
core.c (CONFIG_KPROBE_EVENTS)
uprobe
动态
core.c (CONFIG_UPROBE_EVENTS)
armv8_pmuv3
PERF_TYPE_HARDWARE
arch/arm64 + drivers/perf
五、事件生命周期 5.1 perf_event_open 系统调用 1 2 3 SYSCALL_DEFINE5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t , pid, int , cpu, int , group_fd, unsigned long , flags)
主要步骤:
1 2 3 4 5 6 7 8 1. perf_copy_attr() — 拷贝并校验 attr 2. security_perf_event_open() — LSM 安全检查 3. perf_allow_kernel() — paranoid 权限检查 4. find_lively_task_by_vpid() — 解析目标 task(pid != -1) 5. perf_event_alloc() — 分配 perf_event,匹配 PMU 6. perf_event_set_output() — 关联输出 ring buffer 7. perf_install_in_context() — 安装到 context 并 enable 8. anon_inode 创建 fd — 返回 event fd
5.2 perf_event_alloc 流程 1 2 3 4 5 6 perf_event_alloc(attr, cpu, task, group_leader, ...) → 遍历 pmus 链表,调用 pmu->event_init(event) → 匹配第一个返回 0 的 PMU → 分配 perf_event_context(task 或 cpu) → 初始化 hw_perf_event 状态 → inherit 处理(子进程继承)
5.3 安装到上下文 1 2 3 4 5 6 7 8 perf_install_in_context(ctx, event, cpu) → 若在目标 CPU 上:直接 __perf_install_in_context() → 否则:smp_call_function_single / task_function_call 远程安装 __perf_install_in_context(): → list_add_event() + perf_group_attach() → ctx_sched_in() — 调度事件到硬件 → event->state = PERF_EVENT_STATE_ACTIVE
5.4 事件状态机 1 2 3 4 PERF_EVENT_STATE_INACTIVE → add/start → PERF_EVENT_STATE_ACTIVE PERF_EVENT_STATE_ACTIVE → stop/del → PERF_EVENT_STATE_INACTIVE PERF_EVENT_STATE_ERROR — 初始化失败 PERF_EVENT_STATE_OFF — 被显式 disable
六、上下文调度机制 6.1 调度优先级 硬件 PMU 计数器数量有限,多个事件竞争时需按优先级调度:
1 2 3 4 5 优先级(高 → 低): 1. CPU pinned (EVENT_CPU | EVENT_PINNED) 2. task pinned (EVENT_PINNED) 3. CPU flexible (EVENT_CPU | EVENT_FLEXIBLE) 4. task flexible (EVENT_FLEXIBLE)
6.2 ctx_resched 流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 static void ctx_resched (struct perf_cpu_context *cpuctx, struct perf_event_context *task_ctx, enum event_type_t event_type) { perf_pmu_disable(cpuctx->ctx.pmu); task_ctx_sched_out(cpuctx, task_ctx, event_type); cpu_ctx_sched_out(cpuctx, ctx_event_type); perf_event_sched_in(cpuctx, task_ctx); perf_pmu_enable(cpuctx->ctx.pmu); }
6.3 任务切换时的 perf 处理 1 2 3 4 context_switch(old, new) → perf_event_context_sched_out(old) // 卸载 old task 的 perf events → perf_event_context_sched_in(new) // 加载 new task 的 perf events → perf_cgroup_switch() // cgroup perf 时间戳更新
6.4 Mux 轮转(hrtimer) 当 flexible 事件数超过硬件 counter 数量时,通过 hrtimer 周期性轮转计数器,使各事件共享硬件资源:
1 2 3 perf_mux_hrtimer_handler() → perf_rotate_context(cpuctx) → ctx_resched() — 切换 active 事件组
七、环形缓冲区(ring_buffer.c) 7.1 设计目标
内核 NMI/IRQ 上下文写入,用户态 mmap 读取
支持 overwrite 模式(环形覆盖)和 lossless 模式(缓冲区满则丢弃)
支持 AUX 区域 (ARM SPE、Intel PT 等辅助追踪数据)
正确的内存屏障保证无锁 SPSC(单生产者单消费者)语义
7.2 生产者-消费者同步 1 2 3 4 5 6 7 8 kernel (producer) userspace (consumer) ───────────────── ───────────────────── if (LOAD ->data_tail) { LOAD ->data_head (A) control dep smp_rmb() (C) STORE $data LOAD $data smp_wmb() (B) smp_mb() (D) STORE ->data_head STORE ->data_tail }
A ↔ D :control dependency / full barrier
B ↔ C :WMB / RMB 配对
7.3 嵌套写入(nest 计数) NMI 可能嵌套在 IRQ 采样中,rb->nest 确保只有最外层写入完成后才发布 data_head:
1 2 3 perf_output_get_handle() → rb->nest++ perf_output_put_handle() → 仅 nest==1 时更新 user_page->data_head
7.4 关键 API
函数
功能
rb_alloc()
分配 perf_buffer 及 data pages
perf_output_begin/end()
开始/结束一次 sample 写入
perf_event_wakeup()
水位线到达时 irq_work 唤醒 poll
rb_alloc_aux()
分配 AUX 追踪区域
perf_mmap_to_page()
mmap fault 处理,映射 data page
八、采样与输出(core.c) 8.1 溢出处理链 1 2 3 4 5 6 7 8 9 10 PMU 中断 / hrtimer / tracepoint 触发 → __perf_event_overflow(event, data, regs) → 频率节流检查 → 调用 event->overflow_handler() → 默认:perf_event_output() → BPF attach:bpf_overflow_handler() → bpf_prog_run() → perf_prepare_sample() — 填充 sample 字段 → output_begin() — 获取 ring buffer 空间 → perf_output_sample() — 写入 PERF_RECORD_SAMPLE → perf_output_end() — 发布 head
8.2 sample_type 字段
标志
内容
PERF_SAMPLE_IP
指令指针
PERF_SAMPLE_TID
pid/tid
PERF_SAMPLE_TIME
时间戳
PERF_SAMPLE_CALLCHAIN
调用栈
PERF_SAMPLE_REGS
寄存器快照
PERF_SAMPLE_STACK_USER
用户栈 dump
PERF_SAMPLE_DATA_SRC
内存访问来源(cache level 等)
8.3 权限与安全
sysctl
默认值
说明
kernel.perf_event_paranoid
2
≥2 仅允许用户态事件;0 允许内核态;<0 无限制
kernel.perf_event_mlock
~516 KB
每用户 perf mmap 锁定内存上限
kernel.perf_event_max_sample_rate
100000
最大采样频率 (Hz)
kernel.perf_cpu_time_max_percent
25
perf 采样占用 CPU 时间上限 (%)
九、调用栈回溯(callchain.c) 9.1 功能 当 sample_type 包含 PERF_SAMPLE_CALLCHAIN 时,在采样点收集内核/用户态调用栈。
9.2 架构 hook 1 2 3 4 __weak void perf_callchain_kernel (struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) ;__weak void perf_callchain_user (struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) ;
ARM64 在 arch/arm64/kernel/perf_callchain.c 中实现栈展开(frame pointer / ORC)。
9.3 缓冲区管理 1 2 3 4 5 6 perf_callchain(event, regs) → get_recursion_context() — NMI/IRQ/softirq 递归保护 → get_callchain_entry() — 获取 per-CPU 预分配 buffer → perf_callchain_kernel() — 内核栈 → perf_callchain_user() — 用户栈 → put_callchain_entry()
缓冲区按 CPU 预分配(NMI 安全,不能用 percpu API)
sysctl perf_event_max_stack 控制最大栈深度(默认 127)
十、硬件断点(hw_breakpoint.c) 10.1 概述 利用 CPU Debug 寄存器 (ARM64 DBGBCR/DBGBVR)实现数据/指令断点,集成到 perf_event 框架。
10.2 Slot 约束管理 硬件断点寄存器数量有限(ARM64 通常每 CPU 若干组),需全局约束:
1 2 3 4 struct bp_cpuinfo { unsigned int cpu_pinned; // 该 CPU 上 pinned 断点数 struct bp_slots_histogram tsk_pinned; // 任务级 pinned 直方图 };
函数
功能
reserve_bp_slot()
注册前检查并预留 slot
release_bp_slot()
释放 slot
register_user_hw_breakpoint()
用户态 API:注册任务级断点
register_wide_hw_breakpoint()
全 CPU 范围断点
10.3 断点类型
类型
说明
HW_BREAKPOINT_R
读访问断点
HW_BREAKPOINT_W
写访问断点
HW_BREAKPOINT_RW
读写断点
HW_BREAKPOINT_X
指令执行断点
10.4 与 perf 集成 1 2 3 4 5 6 7 static struct pmu perf_breakpoint = { .event_init = hw_breakpoint_event_init, .add = hw_breakpoint_add, .del = hw_breakpoint_del, };
用户态通过 perf_event_open 设置 type=PERF_TYPE_BREAKPOINT 创建硬件断点事件。
十一、用户态探针(uprobes.c) 11.1 概述 Uprobes 在用户态可执行文件的指定偏移插入软件断点,命中时执行 probe handler(如 perf 采样、kprobe 式追踪)。
11.2 核心数据结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 struct uprobe { struct rb_node rb_node ; struct inode *inode ; loff_t offset; struct arch_uprobe arch ; struct uprobe_consumer *consumers ; struct list_head pending_list ; }; struct uprobe_task { struct uprobe *active_uprobe ; enum uprobe_task_state state ; };
11.3 工作流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 注册阶段: uprobe_register(inode, offset, consumer) → 插入 uprobes_tree (rbtree) → uprobe_apply() — 对已映射的 VMA 插入 SW breakpoint 命中阶段: 用户态执行到断点 → CPU debug exception → uprobe_pre_sstep_notifier() — 设置 TIF_UPROBE → 返回用户态路径:uprobe_notify_resume() → handle_swbp() → 分配 XOL slot → 复制原始指令到 XOL 区域 → 单步执行原始指令 → uprobe_post_sstep_notifier() — 单步完成 → handle_singlestep() — 恢复断点,调用 consumer handler 进程 fork/mmap: uprobe_mmap() — 新映射时自动插入断点 uprobe_dup_mmap() — fork 时复制 uprobe 状态
11.4 XOL(Execute Out of Line) 由于断点指令覆盖了原始指令,需在独立的匿名可执行页中保存并执行原始指令:
1 2 3 原始 VMA: [SW BREAKPOINT] [next insn...] XOL area: [original insn] [jump back] ↑ 单步在此执行
11.5 与 perf 集成 1 2 3 4 perf_pmu_register(&perf_uprobe, "uprobe" , -1 );
十二、用户态接口 12.1 系统调用
调用
功能
perf_event_open(2)
创建/打开 perf event
perf_event_read(2)
读取计数值(部分架构)
perf_event_read_value(2)
读取 enabled/running/count
perf_event_query_bpf(2)
查询/attach BPF 程序
12.2 mmap 映射 1 2 fd = perf_event_open(&attr, pid, cpu, -1, 0); mmap(addr, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
映射布局:
pgoff
内容
0
perf_event_mmap_page(meta page:data_head/data_tail/time/…)
1..N
数据页(sample records)
aux_offset..
AUX 区域(可选,ARM SPE 等)
12.3 常用 perf 命令对应
命令
内核路径
perf stat -e cycles
PERF_TYPE_HARDWARE → armv8_pmuv3 PMU
perf record -e syscalls:sys_enter_openat
PERF_TYPE_TRACEPOINT
perf probe -x ./a.out:main
uprobe PMU
perf record -e cpu-cycles -g
callchain.c 栈回溯
perf record -e 'mem:0x1000'
hw_breakpoint PMU
十三、RK3588/ARM64 平台说明 13.1 Kconfig 支持 1 2 3 4 5 6 7 # arch/arm64/Kconfig select HAVE_PERF_EVENTS select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP config ARCH_SUPPORTS_UPROBES def_bool y
RK3588 默认启用 CONFIG_PERF_EVENTS、CONFIG_HAVE_HW_BREAKPOINT、CONFIG_UPROBES。
13.2 CPU PMU(Cortex-A76 + A55)
特性
说明
PMU 版本
ARMv8 PMUv3(armv8_pmuv3)
计数器数
每 CPU 通常 6 个通用计数器 + 1 个 cycle counter
big.LITTLE
PERF_PMU_CAP_HETEROGENEOUS_CPUS — A76/A55 事件编码可能不同
驱动路径
drivers/perf/arm_pmu.c + arch/arm64/kernel/perf_event.c
常见事件
cycles、instructions、cache-refills、branch-misses
13.3 big.LITTLE 注意事项 RK3588 的 4×A76 + 4×A55 属于异构 CPU:
同一 attr.config 在不同核心上可能映射到不同硬件事件
perf stat 跨核心统计时需注意 event 兼容性
可通过 -C 绑定特定 CPU 或 --no-aggr 分核统计
13.4 KVM PMU arch/arm64/kvm/pmu-emul.c 为 guest 提供 PMU 模拟:
guest 访问 PMUSERENR/PMCR 等寄存器时 trap 到 host
host 侧创建真实 perf_event 计数 guest 活动
kvm_arm_pmu_available static key 控制是否启用
13.5 硬件断点(ARM64)
使用 Debug 架构的 Breakpoint Value/Control 寄存器
每 CPU 有限数量的 breakpoint/watchpoint slot
hw_breakpoint.c 统一管理 slot 分配,防止超限
gdb watch/break 命令底层使用此机制
13.6 uprobes(ARM64)
arch/arm64/include/asm/uprobes.h 定义 struct arch_uprobe
断点指令:BRK #0x004d(UPROBE_SWBP_INSN)
XOL 单步:arch_uprobe_skip_sstep() 处理 PC 对齐
十四、完整 perf record 时序 以 perf record -e cycles -c 10000 ./app 为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [用户态 perf] perf_event_open(PERF_TYPE_HARDWARE, config=cycles, sample_period=10000) → core.c: SYSCALL_DEFINE5(perf_event_open) → 匹配 armv8_pmuv3 PMU → perf_event_alloc() + perf_install_in_context() → ctx_sched_in() → pmu->add() → 编程 PMU 计数器 mmap(fd) → ring_buffer.c: perf_mmap() → 分配 perf_buffer + data pages → 映射 meta page (data_head/data_tail) + data pages [app 运行] CPU 执行 app 指令,PMU cycle counter 递减 counter 归零 → PMU 溢出中断 → arch/arm64/kernel/perf_event.c: arm_pmu interrupt handler → __perf_event_overflow() → perf_prepare_sample(IP, TID, TIME, ...) → perf_callchain() (若 -g 启用) → perf_output_begin/end() → 写入 ring buffer → perf_event_wakeup() → irq_work → poll 唤醒 [用户态 perf] poll(fd) 返回 POLLIN 读取 ring buffer: data_tail 追赶 data_head 解析 PERF_RECORD_SAMPLE records 写入 perf.data close(fd) → perf_event_release() → perf_remove_from_context() → ctx_sched_out() → pmu->del() → rb_free() 释放 ring buffer
十五、总结 kernel/events 是 Linux 性能分析与追踪 的核心基础设施:
PMU 抽象 — struct pmu 统一 software、tracepoint、hardware 等各类事件源
上下文调度 — pinned/flexible 优先级 + mux 轮转,在有限硬件计数器上 multiplex 多事件
环形缓冲区 — 无锁 SPSC mmap 缓冲区,NMI 安全的嵌套写入
采样链 — overflow → prepare_sample → callchain → output → wakeup
硬件断点 — Debug 寄存器 slot 约束管理,集成 perf_event 框架
Uprobes — 用户态软件断点 + XOL 单步,支持 perf probe 动态追踪
安全控制 — paranoid 级别、mlock 限制、LSM 集成
RK3588 作为 ARM64 big.LITTLE 平台,通过 drivers/perf/arm_pmu.c 和 arch/arm64/kernel/perf_event.c 提供 CPU PMU 支持;kernel/events 中的 core、ring_buffer、callchain、hw_breakpoint、uprobes 等模块在 RK3588 上完整可用,是 perf stat/record/top、eBPF 性能工具、gdb 硬件断点等功能的内核基础。
附录:源文件清单
文件
行数
分类
core.c
~13825
perf 核心框架
ring_buffer.c
~972
mmap 环形缓冲区
callchain.c
~253
调用栈回溯
hw_breakpoint.c
~1051
硬件断点
uprobes.c
~2360
用户态探针
hw_breakpoint_test.c
~333
KUnit 测试
internal.h
~247
内部头文件
RK3588 相关架构/驱动文件 :
文件
功能
arch/arm64/kernel/perf_event.c
ARM64 PMU 驱动
arch/arm64/kernel/perf_callchain.c
ARM64 栈展开
arch/arm64/kvm/pmu-emul.c
KVM PMU 模拟
drivers/perf/arm_pmu.c
ARM PMU 通用框架
drivers/perf/arm_pmu_platform.c
平台 PMU 注册
include/linux/perf_event.h
公共 API(~1766 行)
正在加载留言…