谷动谷力

标题: Linux内核性能架构:perf_event [打印本页]

作者: 鸣涧    时间: 2022-10-11 22:41
标题: Linux内核性能架构:perf_event
Linux内核性能架构:perf_event
作者简介:
荣涛,csdn博主。
组件概述

Linux性能子系统在性能分析中非常有用。以下显示了这篇文章中的perf子系统componenet 。

“ perf”是可用于执行性能分析的用户程序。

仅暴露给用户空间的系统调用perfeventopen返回一个perf事件fd。该系统调用没有glibc包装器。更多信息可以在手册页中阅读。此功能是最复杂的功能之一。

“ perf_event”是内核中的核心结构。性能事件有几种类型,例如跟踪点,软件,硬件。

我们还可以通过perf event fd将eBPF程序附加到trae事件。

抽象层

以下显示了perf的抽象层。

每个类型的性能事件都有一个对应的PMU(性能监视单元)。例如,跟踪点pmu具有以下pmu。


与硬件相关的PMU具有与arch-spec有关的抽象结构,例如'struct x86_pmu'。与硬件相关的结构将读取/写入性能监视器MSR。

每个PMU都通过调用“ perf_pmu_register”进行注册。

性能事件上下文

性能可以监视cpu相关事件和任务相关事件。他们两个都可以有几个受监视的事件。因此,我们需要一个上下文来连接事件。这是“ perf_event_context”。

有两种上下文,软件和硬件,定义如下:

对于CPU级别,上下文定义为“ perf_cpu_context”,并在“ struct pmu”中定义为percpu变量。


如果PMU是相同类型,则它们将共享一个“ struct perf_cpu_context”。

下图显示了此帖子中的相关结构。


对于任务级别,“ task_struct”具有如下定义的指针数组:

下图显示了相关结构,也来自于该帖子。


CPU在线时将触发CPU级性能事件。但是对于任务级别的perf事件,只能通过运行任务来触发它。“ perf_cpu_context”的task_ctx包含当前正在运行的任务的perf上下文。

性能事件上下文时间表

性能的一项工作是安排任务的perf_event_context的进出时间。

下图显示了与性能相关的任务计划输入和输出功能。

最后,将调用PMU的add和del回调。让我们以跟踪点为例。add回调是“ perf_trace_add”,而del回调是“ perf_trace_add”。

          int perf_trace_add(struct perf_event *p_event, int flags)

“ perf_event”将被添加或删除到“ tp_event-> perf_events”列表中。

perf_event_open流

perf_event_open将调用'pmu-> event_init'来初始化事件。并将perf_event添加到perf_event_context中。

性能跟踪事件

回顾跟踪点PMU的定义。

让我们尝试看一下perf子系统如何监视跟踪点事件。

性能事件初始化
称为“ perf_tp_event_init”。

'perf_trace_init'将找到指定的跟踪点。

“ perf_trace_event_reg”将分配并初始化“ tp_event_perf_events”列表。并使用TRACE_REG_PERF_REGISTER调用“ tp_event-> class-> reg”。

“ tp_event_> class-> reg”回调为“ trace_event_reg”。

我们可以看到'call-> class-> perf_probe'将被注册到跟踪点。从我的帖子。我们知道这个“ perf_probe”是“ perf_trace _ ## call”。


如果“ event_call-> perf_events”为空,则表示没有任何当前的perf_event添加到该跟踪点。这是'perf_event_open'初始化perf_event时的默认状态。

性能事件添加

在CPU中调度任务时,将调用'pmu-> add',并将'perf_event'链接到'event_call-> perf_events'链接列表。

性能事件

从CPU调度任务后,将调用“ pmu-> del”,并且将从“ event_call-> perf_events”链接列表中删除“ perf_event”。

性能事件触发器

如果'event_call-> perf_events'不为空,则将调用'perf_trace_run_bpf_submit'。如果没有附加eBPF程序,则将调用“ perf_tp_event”。

对于“ event_call-> perf_events”列表中的每个“ perf_event”。它调用perf_swevent_event触发性能事件。

'perf_swevent_event'添加'event-> count'。如果事件未采样,则仅返回。Tis是性能计数模式。如果perf_event在样本模式下,则需要复制跟踪点数据。以下是呼叫链。

软件性能事件

软件PMU定义如下:

性能事件初始化

“ perf_swevent_init”将被调用。它称为“ swevent_hlist_get”

这将创建一个percpu'swhash-> swevent_hlist'列表。还要将perf_swevent_enabled [event_id]设置为true。

性能事件添加

'perf_swevent_add'将perf_event添加到percpu哈希列表中。

性能事件

'perf_swevent_del'从哈希列表中删除。


性能事件触发器

以任务开关为例。

“ perf_sw_event_sched”将被调用。

在perf_event_task_sched_out-> _perf_sw_event-> do_perf_sw_event调用链之后。

如我们所见,它最终会调用“ perf_swevent_event”来触发事件。

硬件性能事件

硬件PMU之一定义如下:

硬件性能事件非常复杂,因为它将与硬件交互。这里不会深入介绍硬件。

性能事件初始化

此处的“ x86_pmu”是基于arch规范的PMU结构。

性能事件添加

x86_pmu_add->收集事件->-> x86_pmu.schedule_events()-> x86_pmu.add

'collect_events'集

性能事件

x86_pmu_del将删除“ cpuc-> event_list”中的事件。

性能事件触发器

触发硬件事件时,它将触发NMI中断。此处理程序是“ perf_event_nmi_handler”。

以Taks'x86_pmu.handle_irq'= x86_pmu_handle_irq为例。

在这里,我们可以看到它对“ cpuc”进行了迭代,以查找触发该中断的事件。

参考资料:

Linux kernel perf architecture (terenceli.github.io)








欢迎光临 谷动谷力 (http://bbs.sunsili.com/) Powered by Discuz! X3.2