尧图精选

Linux 内核 Marvell PEM PMU(mrvl_pcie_rc_pmu):用 perf 测量 PCIe 根端口流量与 ATS 延迟

🕒 发布时间:2026/9/9 23:35:24 📁 来源:尧图网络
Linux 内核 Marvell PEM PMUmrvl_pcie_rc_pmu用 perf 测量 PCIe 根端口流量与 ATS 延迟【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linuxMarvell Odyssey 平台的 PCI Express 接口单元PEM配有一个专用的非核心uncore性能监控单元本指南基于内核文档 mrvl-pem-pmu.rst 与驱动实现 marvell_pem_pmu.c完整讲清该 PMU 监控哪些 PCIe 事务与 ATS 事件、26 个 perf 事件的 sysfs 暴露方式以及驱动如何通过“自由运行计数器 差值采样”完成统计帮助你在 Marvell Thunder/Odyssey 平台上完成 PCIe 链路吞吐与延迟性能分析。1. PEM PMU 监控什么PCIe RC 流量与 ATS 事件每个 PCIe 接口单元PEM都关联一个监控单元其中包含一组性能计数器用于追踪通过 PCIe 链路传输数据时的各项特征。计数器追踪入站inbound与出站outbound事务并对以下 TLPTransaction Layer Packet类型分别计数PostedP/ Non-postedNP/ CompletionCPLTLP三种 TLP 各有独立的 64 位计数器入站与出站内存读请求以及它们的延迟ATSAddress Translation Service事件包括 ATS Translation、ATS Page Request、ATS Invalidation以及对应的延迟计数器。文档特别指出入站与出站事务中的 posted/non-posted/completion TLP 各有独立的 64 位计数器来测量ATS 事件则由另一组独立计数器测量。驱动源码中的事件枚举marvell_pem_pmu.c与文档描述一一对应共 26 个事件IB入站10 个TLP 计数NPR/PR/CPL、TLP payload 的 Dword 计数NPR/PR/CPL、inflight 事务数、读请求数、两类异常读请求计数OB出站10 个TLP 计数、Dword 计数、inflight、读请求、以及 TLP 合并merges计数ATS 6 个三类事件各配一个“事件计数 延迟”计数器。其中IB_REQ_NO_RO_NCB、IB_REQ_NO_RO_EBUS这两个事件在仓库文档中没有更详细的语义说明仅能确认它们属于入站请求类计数器偏移 0x400 / 0x408。2. 事件在 sysfs 中的暴露方式PMU 驱动通过 sysfs 暴露可用事件与 format 选项路径形如为实例编号即设备物理基地址/sys/bus/event_source/devices/mrvl_pcie_rc_pmu_/events/ /sys/bus/event_source/devices/mrvl_pcie_rc_pmu_/format/每个events/下的属性文件内容为event0xid见 pem_pmu_event_showformat/下只有一个event属性定义为config:0-5marvell_pem_pmu.c即事件 ID 占用attr.config的低 6 位可容纳 64 个事件 ID当前实现 26 个。执行perf list | grep mrvl_pcie_rc_pmu可以看到全部事件文档中的原始输出为实例后缀# perf list | grep mrvl_pcie_rc_pmu mrvl_pcie_rc_pmu_/ats_inv/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ats_inv_latency/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ats_pri/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ats_pri_latency/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ats_trans/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ats_trans_latency/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_inflight/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_reads/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_req_no_ro_ebus/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_req_no_ro_ncb/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_tlp_cpl_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_tlp_dwords_cpl_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_tlp_dwords_npr/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_tlp_dwords_pr/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_tlp_npr/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ib_tlp_pr/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_inflight_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_merges_cpl_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_merges_npr_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_merges_pr_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_reads_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_tlp_cpl_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_tlp_dwords_cpl_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_tlp_dwords_npr_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_tlp_dwords_pr_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_tlp_npr_partid/ [Kernel PMU event] mrvl_pcie_rc_pmu_/ob_tlp_pr_partid/ [Kernel PMU event]注意事件命名中带有_partid后缀的属性如ob_tlp_npr_partid、ib_tlp_cpl_partid这是驱动在 pem_perf_events_attrs 属性表 中定义的 sysfs 属性名从命名看与按 partition ID 区分的计数有关但仓库文档未给出进一步说明。2.1 事件与计数器寄存器偏移每个事件对应一个固定偏移的 64 位寄存器映射表定义在 eventid_to_offset_table事件枚举名sysfs 事件名寄存器偏移含义IB_TLP_NPRib_tlp_npr0x000入站 Non-posted TLP 数IB_TLP_PRib_tlp_pr0x008入站 Posted TLP 数IB_TLP_CPLib_tlp_cpl_partid0x010入站 Completion TLP 数IB_TLP_DWORDS_NPRib_tlp_dwords_npr0x100入站 NP TLP payload Dword 数IB_TLP_DWORDS_PRib_tlp_dwords_pr0x108入站 P TLP payload Dword 数IB_TLP_DWORDS_CPLib_tlp_dwords_cpl_partid0x110入站 CPL TLP payload Dword 数IB_INFLIGHTib_inflight0x200入站 in-flight 事务IB_READSib_reads0x300入站内存读请求IB_REQ_NO_RO_NCBib_req_no_ro_ncb0x400入站请求NCB 类IB_REQ_NO_RO_EBUSib_req_no_ro_ebus0x408入站请求EBUS 类OB_TLP_NPRob_tlp_npr_partid0x500出站 Non-posted TLP 数OB_TLP_PRob_tlp_pr_partid0x508出站 Posted TLP 数OB_TLP_CPLob_tlp_cpl_partid0x510出站 Completion TLP 数OB_TLP_DWORDS_NPRob_tlp_dwords_npr_partid0x600出站 NP TLP payload Dword 数OB_TLP_DWORDS_PRob_tlp_dwords_pr_partid0x608出站 P TLP payload Dword 数OB_TLP_DWORDS_CPLob_tlp_dwords_cpl_partid0x610出站 CPL TLP payload Dword 数OB_INFLIGHTob_inflight_partid0x700出站 in-flight 事务OB_READSob_reads_partid0x800出站内存读请求OB_MERGES_NPRob_merges_npr_partid0x900出站 NP TLP 合并数OB_MERGES_PRob_merges_pr_partid0x908出站 P TLP 合并数OB_MERGES_CPLob_merges_cpl_partid0x910出站 CPL TLP 合并数ATS_TRANSats_trans0x2D18ATS Translation 事件数ATS_TRANS_LATENCYats_trans_latency0x2D20ATS Translation 延迟ATS_PRIats_pri0x2D28ATS Page Request 事件数ATS_PRI_LATENCYats_pri_latency0x2D30ATS Page Request 延迟ATS_INVats_inv0x2D38ATS Invalidation 事件数ATS_INV_LATENCYats_inv_latency0x2D40ATS Invalidation 延迟3. 源码解析自由运行计数器与差值采样机制驱动注释明确说明每个事件都映射到一个自由运行free running的 64 位计数器硬件上没有事件使能/控制位只能复位marvell_pem_pmu.c。整个驱动从头到尾没有任何 MMIO 写操作唯一的硬件访问是 pem_perf_read_counter 中的readq_relaxed(pmu-base offset)读取。因此驱动采用“快照 差值”策略startpem_perf_event_start计数器一直在硬件中运行驱动只是把当前读数存入hwc-prev_count作为基准updatepem_perf_event_update再次读取计数器用do { ... } while (local64_xchg(...))的 CAS 循环防止并发更新竞争然后把“新值 − 旧值”累加到event-countadd/delhwc-idx直接取自event-attr.config即事件 ID025越界时WARN_ON_ONCE并返回-EINVALpem_perf_event_add。这一设计意味着该 PMU 是纯**计数型counting**uncore PMU使用上有三点硬性限制均实现在 pem_perf_event_init不支持采样is_sampling_event(event)或带PERF_ATTACH_TASK的事件直接返回-EOPNOTUPP只能配合perf stat这类计数场景使用不能用perf record采样绑定单个 CPU事件被强制归属到 PMU 实例绑定的 CPUevent-cpu pmu-cpu同一个事件不能同时在多个 CPU 上观察不允许混合 PMU 事件组事件组中若混入其他 PMU 的事件会被拒绝。此外PMU 注册时设置了PERF_PMU_CAP_NO_EXCLUDE且task_ctx_nr perf_invalid_contextpem_perf_probe表明它是系统级非任务上下文PMU也不支持按进程/线程排除统计。3.1 CPU 下线时的上下文迁移PMU 实例在 probe 时绑定到当时的 CPUraw_smp_processor_id()。由于事件上下文绑定在该 CPU 上一旦该 CPU 下线pem_pmu_offline_cpu 回调会通过perf_pmu_migrate_context()把上下文迁移到任意一个仍在线的 CPU并把pmu-cpu更新为目标 CPU。该回调挂在内核 CPU 热插拔状态CPUHP_AP_PERF_ARM_MRVL_PEM_ONLINE上定义于 cpuhotplug.h保证 perf 统计在 CPU 热插拔场景下不丢失。4. 驱动注册ACPI 匹配与 PMU 命名驱动是一个 platform driverpem_pmu_driver关键点ACPI 匹配仅通过 ACPI IDMRVL000E匹配pem_pmu_acpi_match即该驱动面向通过 ACPI 描述的 Marvell 平台Thunder/Odyssey 家族 SoCioremap 第一个资源devm_platform_get_and_ioremap_resource(pdev, 0, res)取得计数器寄存器基地址作为pmu-basePMU 命名实例名为mrvl_pcie_rc_pmu_%llx%llx填入的就是该 PCI 资源的物理基地址marvell_pem_pmu.c这解释了文档中mrvl_pcie_rc_pmu_实例后缀的由来——每个 PCIe RC 实例对应一个 PMUKconfigCONFIG_MARVELL_PEM_PMUtristateMARVELL PEM PMU Support依赖ARCH_THUNDER || (COMPILE_TEST 64BIT)见 drivers/perf/Kconfig构建规则在 drivers/perf/Makefile。也就是说该驱动正式目标是ARCH_THUNDERMarvell Thunder 架构即 Odyssey 系列其余 64 位平台仅在 COMPILE_TEST 下参与编译测试。适用前提小结需要在 Marvell Thunder/Odyssey 硬件ACPI 描述、含MRVL000E设备上启用CONFIG_MARVELL_PEM_PMU并加载该模块或编入内核/sys/bus/event_source/devices/下才会出现mrvl_pcie_rc_pmu_addr设备。5. 实战用 perf 统计 PCIe RC 流量文档给出的标准用法是perf stat。在跑业务负载时同时统计入站在飞事务、入站读请求及两类入站请求计数# perf stat -e ib_inflight,ib_reads,ib_req_no_ro_ebus,ib_req_no_ro_ncb workload由于这些事件名只属于该 PMUperf 可以直接解析不带前缀的事件名如果需要显式指定实例系统中存在多个mrvl_pcie_rc_pmu_addr实例时尤其有用应使用perf list输出的全限定语法例如# 统计某个实例的出站 Posted TLP 数与 payload 体积 perf stat -e mrvl_pcie_rc_pmu_addr/ob_tlp_pr_partid/,\ mrvl_pcie_rc_pmu_addr/ob_tlp_dwords_pr_partid/ workload典型分析场景均可直接用上述 26 个事件组合实现链路吞吐*_tlp_dwords_*系列事件 × 4 字节即为 payload 传输量配合*_tlp_*事件数可算出平均 TLP 大小读延迟/带宽ib_reads/ob_reads_partid与 in-flight 计数ib_inflight/ob_inflight_partid配合观察内存读压力TLP 合并效率ob_merges_*_partid反映出站 TLP 的合并程度合并越多、单事务开销越低ATS 开销启用 SR-IOV/ATS 的设备ats_trans、ats_pri、ats_inv三个事件计数与对应_latency延迟计数器用于评估地址翻译、页面请求与失效的开销。注意由于第 3 节所述的限制该 PMU 事件只支持perf stat式计数perf record采样或按进程附着-p到特定任务上下文之外的 uncore 用法不受限但--task类附着会得到-EOPNOTSUPP错误若绑定的 CPU 被下线统计上下文会自动迁移但perf stat的-C参数指定 CPU 时应避开即将下线的 CPU。6. 参考资料仓库内路径文档Documentation/admin-guide/perf/mrvl-pem-pmu.rst驱动实现drivers/perf/marvell_pem_pmu.c配置项drivers/perf/Kconfig、drivers/perf/MakefileCPU 热插拔状态定义include/linux/cpuhotplug.hperf 文档索引Documentation/admin-guide/perf/index.rst【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →