PMU 中断:如何处理它们

PMU 中断:如何处理它们

💡 原文中文,约2800字,阅读约需7分钟。
📝

内容提要

PMU(性能监控单元)通过计数器记录CPU周期、指令数、分支预测错误等硬件事件,计数器溢出时触发PMU中断通知软件。在Armv8 Linux内核中,需先注销内置arm-pmu处理程序,再用request_irq()注册自定义处理函数,并设置IRQF_SHARED等标志。也可在固件EL3中处理,或直接用perf工具监控。

🔎

延伸解读

PMU 中断的触发机制与软件控制

PMU 计数器溢出时才会触发中断,而非每次事件递增。计数器是可读写的 32 位寄存器,软件可通过写入初值控制中断时机。例如,每次中断后将寄存器重置为最大值,可实现每次事件都触发中断;也可动态调整初值,在性能与准确性之间权衡。这种灵活性让开发者能根据需求定制监控粒度。

内核中自定义 PMU 中断处理的步骤

在 Armv8 Linux 中,内置的 arm-pmu 处理程序已占用中断。要注册自定义处理函数,需先注销内置处理程序,或修改内核源码为其添加 IRQF_SHARED 标志,使中断可共享。然后通过 request_irq() 注册,传入逻辑中断 ID 和 IRQF_PERCPU 等标志。注意逻辑中断 ID 与硬件中断 ID 的映射关系,可通过 /proc/interrupts 查看。

固件层处理 PMU 中断的适用场景

对于不想侵入操作系统的跟踪器,可在固件中处理 PMU 中断。需配置 GIC 将中断路由到最高安全级别 EL3,并在 ATF 中注册处理程序;也可重新路由到 Secure-EL1,在自有的 TEE-OS 中处理。这种方式适合安全敏感或与 OS 隔离的监控需求,但实现复杂度较高。

使用 perf 工具简化 PMU 监控

若不想自行处理中断,可直接使用 perf 工具。perf 依赖 Linux 内置的 PMU 中断处理程序,能监控多种硬件事件,无需编写内核模块。对于大多数性能分析场景,perf 提供了简单高效的途径,避免了自定义中断处理的复杂性和潜在风险。

❓

Q&A

PMU是什么?它有什么作用?

PMU是性能监控单元(Performance Monitor Unit)的缩写,它是一组可以计数核心中任何可用事件的计数器,用于监控CPU周期、指令数、分支预测错误等硬件事件,帮助软件了解程序在硬件上的执行情况。

PMU中断什么时候触发?它的目的是什么?

PMU中断仅在PMU计数器溢出时生成。其目的是通知软件计数器将重置为零,软件不应信任结束值减去开始值的结果。

如何在Linux内核中注册自定义的PMU中断处理程序?

首先需要注销内置的arm-pmu处理程序,然后使用request_irq()注册自定义处理函数,并设置IRQF_SHARED等标志。例如:request_irq(irq_id, pmu_irq_handler, IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED, "pmi_handler", (void*)pmu_irq_handler);

为什么需要注销内置的arm-pmu处理程序?

因为通常一个中断只能有一个处理程序,而Linux已经内置了arm-pmu处理程序。为了注册自定义处理程序,必须先注销它,或者修改内置处理程序添加IRQF_SHARED标志使其可共享。

除了在内核中处理PMU中断,还有哪些方式?

还可以在固件EL3中处理PMU中断,需要配置GIC将中断路由到EL3,并在ATF中注册处理程序;或者使用perf工具,这是最简单的方式,无需自己处理中断。

perf工具与PMU有什么关系?

perf是使用PMU的最简单方式,它利用PMU监控硬件事件,并且Linux内置的PMU中断处理程序正是为perf服务的。

🏷️

标签

➡️

继续阅读