拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Linux 内核 HiSilicon SoC Uncore PMU 实战指南:L3C/HHA/DDRC 的 perf 事件采集与过滤配置

Linux 内核 HiSilicon SoC Uncore PMU 实战指南L3C/HHA/DDRC 的 perf 事件采集与过滤配置【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linuxHiSilicon SoC 内部的 L3 缓存L3C、Hydra Home AgentHHA与 DDR 控制器DDRC等系统级设备各自内置独立的 uncore 性能监控单元PMU。本文基于内核文档 Documentation/admin-guide/perf/hisi-pmu.rst 与驱动源码 drivers/perf/hisilicon/完整讲解 HiSilicon uncore PMU 的 SoC 拓扑、sysfs 事件发现机制、perf list/perf stat的使用方法以及 PMU v2identifier0x30与 v3identifier0x40新增的tt_core、tt_req、datasrc_cfg、ext、srcid/tgtid等过滤参数帮助你在 HiSilicon 平台上对 NoC、缓存与内存子系统做精细的性能剖析。HiSilicon SoC 拓扑SCCL、CCL 与 uncore 设备理解 uncore PMU 之前先要理解 HiSilicon SoC 的层次化封装结构。根据官方文档的描述HiSilicon SoC 芯片集成了多种相互独立的系统设备 PMU例如 L3 缓存L3C、Hydra Home AgentHHA和 DDRC。这些 PMU 彼此独立各自拥有硬件逻辑来采集统计与性能信息SoC 封装了多个 CPU die 与 IO die。每个 CPU 簇CPU ClusterCCL由 4 个 CPU 核心组成共享一片 L3 缓存每个 CPU die 被称为 Super CPU ClusterSCCL由 6 个 CCL 构成每个 SCCL 配备 2 个 HHA编号 0–1和 4 个 DDRC编号 0–3。PMU v2 之后的 SoC 进一步封装了 I/O dieI/O die 被称为 Super I/O ClusterSICL包含多个 I/O ClusterICL。SoC 中每个 CCL/ICL 都有唯一的 11 位 ID其中高 6 位是 SCCL-ID低 5 位是 CCL/ICL-ID。文档列出了 I/O die 上各 ICL 类型的编码低 5 位编码ICL 类型5b00000I/O_MGMT_ICL5b00001Network_ICL5b00011HAC_ICL5b10000PCIe_ICL这套拓扑在驱动中由struct hisi_pmu_topology表达见 hisi_uncore_pmu.h其中sccl_id/sicl_id/scl_id三者共用一个 unionSCCL 与 SICL 是平行的一个 PMU 不可能同时位于两者之上ccl_id表示 CPU 簇index_id表示同位置多个同类 PMU 的模块编号sub_id则是 PMU 的子模块编号——文档注释里明确举例DDRC PMU v2 因为每个 DDRC 内含多个 DMC 而使用了sub_id。任何无法定位的拓扑字段取值为-1。拓扑 ID 的来源在 hisi_uncore_pmu.c 的hisi_uncore_pmu_init_topology()驱动从设备固件属性hisilicon,scl-id、hisilicon,ccl-id、hisilicon,idx-id、hisilicon,sub-id中读取。而对于 CPU 侧hisi_read_sccl_and_ccl_id()hisi_uncore_pmu.c则从MPIDR_EL1的 affinity 层级解析出 SCCL/CCL ID并按 CPU 型号区分三种编码TSV110 的 MT 版本SCCL 取Aff2[7:3]CCL 取Aff2[2:0]其他 MT 部件SCCL 取Aff3[7:0]CCL 取Aff2[7:0]非 MT 部件SCCL 取Aff2[7:0]CCL 取Aff1[7:0]。驱动构建与 sysfs 事件发现编译依赖uncore PMU 驱动族的构建开关在 drivers/perf/hisilicon/KconfigHISI_PMU为 tristate 选项依赖ARM64 ACPI即该套驱动仅面向 ARM64 且使用 ACPI 的 HiSilicon 系统。Makefile 显示CONFIG_HISI_PMU会编译 9 个目标文件hisi_uncore_pmu.o公共框架以及hisi_uncore_l3c_pmu.o、hisi_uncore_hha_pmu.o、hisi_uncore_ddrc_pmu.o、hisi_uncore_sllc_pmu.o、hisi_uncore_pa_pmu.o、hisi_uncore_cpa_pmu.o、hisi_uncore_uc_pmu.o、hisi_uncore_noc_pmu.o、hisi_uncore_mn_pmu.o等具体设备 PMU。此外还有独立的HISI_PCIE_PMU与HNS3_PMU选项分别面向 PCIe 与 HNS3 网卡的 RCiEP 设备与本文的 uncore PMU 主题无关。每个模块注册为独立 PMU文档指出每个 L3C、HHA、DDRC 都会以独立的 PMU 身份向 perf 注册PMU 名称在事件列表中形如hisi_scclsccl-id_moduleindex-id其中sccl-id是 SCCL 标识index-id是模块索引。例如hisi_sccl3_l3c0/rd_hit_cpipeSCCL 3 上第 0 号 L3C 的READ_HIT_CPIPE事件hisi_sccl1_hha0/rx_operationsSCCL 1 上第 0 号 HHA 的RX_OPERATIONS事件。对应地设备节点位于/sys/bus/event_source/devices/hisi_sccl{X}_l3c{Y}/hha{Y}/ddrc{Y}以 L3C 驱动为例hisi_uncore_l3c_pmu.c 的 probe 函数会按拓扑生成名称有sub_id时格式为hisi_sccl%d_l3c%d_%dv3 命名否则为hisi_sccl%d_l3c%d随后调用perf_pmu_register()完成注册。事件与过滤参数则通过 sysfs 的events/与format/属性组暴露perf list就是读取这些属性列出的事件清单。每个 PMU 的 sysfs 属性组都由公共的hisi_pmu_cpumask_attr_group、hisi_pmu_identifier_group与各版本的 format/events 组拼成例如 L3C 的组装见 hisi_uncore_l3c_pmu.c。cpumask 与 associated_cpus文档说明驱动还提供两个额外的 sysfs 属性cpumask显示用于统计该 uncore PMU 事件的 CPU 核心 ID。它是给 perf 等用户态工具的提示hint通常只包含associated_cpus中的某一个关联 CPUassociated_cpus显示与该 PMU 关联的 CPU 集合。源码印证了这一点。hisi_uncore_pmu.c 中cpumask属性只输出单个on_cpuassociated_cpus输出hisi_pmu-associated_cpus位图。on_cpu的选择逻辑在hisi_uncore_pmu_online_cpu()hisi_uncore_pmu.c当某个与 PMU 拓扑关联的 CPU 上线时驱动把该 CPU 记入associated_cpus并将其设为on_cpu同时把 PMU 溢出中断的 affinity 绑到同一 CPU若 PMU 没有关联 CPU例如位于 SICL 上则用cpumask_local_spread()按 NUMA 节点就近选取。当on_cpu离线时hisi_uncore_pmu_offline_cpu()hisi_uncore_pmu.c会通过perf_pmu_migrate_context()把 PMU 上下文迁移到新的关联 CPU 并更新中断亲和性。此外 hisi_uncore_pmu.c 在event_init里会强制执行event-cpu hisi_pmu-on_cpu——同一个 PMU 上的所有事件被约束在同一个 CPU 上计数这与 uncore 计数器在 die 内共享的硬件特性一致。基础用法perf list 与 perf stat文档给出的标准用法如下。先用perf list查看 uncore 事件$# perf list hisi_sccl3_l3c0/rd_hit_cpipe/ [kernel PMU event] ------------------------------------------ hisi_sccl3_l3c0/wr_hit_cpipe/ [kernel PMU event] ------------------------------------------ hisi_sccl1_l3c0/rd_hit_cpipe/ [kernel PMU event] ------------------------------------------ hisi_sccl1_l3c0/wr_hit_cpipe/ [kernel PMU event] ------------------------------------------再对指定 PMU 事件做整机-a统计既可以用事件名也可以用原始事件码$# perf stat -a -e hisi_sccl3_l3c0/rd_hit_cpipe/ sleep 5 $# perf stat -a -e hisi_sccl3_l3c0/config0x02/ sleep 5两条命令等价从源码的事件表 hisi_uncore_l3c_pmu.c 可以确认 L3C PMU v1 注册的事件包括rd_cpipe(0x00)、wr_cpipe(0x01)、rd_hit_cpipe(0x02)、wr_hit_cpipe(0x03)、victim_num(0x04)、rd_spipe(0x20)、wr_spipe(0x21)、rd_hit_spipe(0x22)、wr_hit_spipe(0x23)、back_invalid(0x29)、retry_cpu(0x40)、retry_ring(0x41)、prefetch_drop(0x42)——config0x02正是rd_hit_cpipe。PMU v2identifier 0x30新增过滤能力文档指出 PMU v2 的 identifier 为0x30驱动中定义为 hisi_uncore_pmu.h 的HISI_PMU_V2 0x30拓扑与 v1 相同但硬件增加了一组过滤功能都通过 perf 事件的 config1/config2 字段下发。1. tt_core按核/线程过滤 L3C 计数L3C PMU 支持在簇内按 core/thread 过滤以位图形式指定$# perf stat -a -e hisi_sccl3_l3c0/config0x02,tt_core0x3/ sleep 5上例只统计该簇中 core/thread 0 和 1 产生的操作。注意文档的告诫不要使用tt_core_deprecated指定核/线程过滤该选项仅为向后兼容保留且只支持 8 位可能覆盖不全共享该 L3C 的所有核/线程。源码中这两者的位域定义见 hisi_uncore_l3c_pmu.c 的 v2 format 组event→config:0-7tt_core_deprecated→config1:0-7tt_req→config1:8-10datasrc_cfg→config1:11-15datasrc_skt→config1:16tt_core→config2:0-15。tt_core从 8 位扩展到 16 位以覆盖共享 L3 的全部 CPU。驱动在hisi_l3c_pmu_get_tt_core()hisi_uncore_l3c_pmu.c中优先取config2的新字段为空时回退到旧字段而check_filter()hisi_uncore_l3c_pmu.c同时拒绝了两者同时设置的非法组合。命中过滤后hisi_l3c_pmu_config_core_tracetag()会把位图写入L3C_CORE_CTRL寄存器并置位L3C_PERF_CTRL的核计数使能与 tracetag 核使能hisi_uncore_l3c_pmu.c。2. tt_req按读/写/原子操作类型过滤Tracetagtt_req允许只统计读、写或原子操作缺省为统计全部操作。tt_req是 3 位字段编码如下编码含义3b1000x4读操作3b1010x5写操作3b1100x6原子 store 操作3b1110x7原子非 store 操作其他保留示例$# perf stat -a -e hisi_sccl3_l3c0/config0x02,tt_req0x4/ sleep 5上例只统计该簇内的读操作。实现上hisi_l3c_pmu_config_req_tracetag()hisi_uncore_l3c_pmu.c把tt_req左移 7 位写入L3C_TRACETAG_CTRL的请求类型域并置请求使能位再在L3C_PERF_CTRL中打开L3C_TRACETAG_EN使能位停止时由hisi_l3c_pmu_clear_req_tracetag()对称清除。3. datasrc确认数据来源datasrc用于判断数据从哪里来是 5 位编码。文档列出的重要编码编码数据来源5b00001本 die 的 L3C5b01000跨 diecross-die的 L3C5b01001另一个 socket 中的 L3C5b01110本地 DDR5b01111跨 die 的 DDR5b10000跨 socket 的 DDR主要用途是帮助定位数据源相对 CPU 核心的远近。多芯片场景下使用datasrc_cfg过滤时perf 命令中还需要配置datasrc_skt$# perf stat -a -e hisi_sccl3_l3c0/config0xb9,datasrc_cfg0xE/, \ hisi_sccl3_l3c0/config0xb9,datasrc_cfg0xF/ sleep 5源码侧hisi_l3c_pmu_config_ds()hisi_uncore_l3c_pmu.c将 5 位datasrc_cfg写入每 4 个计数器共享的 8 位数据源类型寄存器前 4 个计数器用L3C_DATSRC_TYPE0后 4 个用L3C_DATSRC_TYPE1若设置了datasrc_skt则置位L3C_DATSRC_CTRL的L3C_DATSRC_SKT_EN。4. uring_channel按 uring 通道过滤 UC PMU 事件UC PMU 的事件0x47~0x59支持按 tx 请求 uring channel 过滤该字段为 2 位编码含义2b11统计发送到 uring_extMATA通道的事件2b01与2b11相同2b10统计发送到 uring非 MATA通道的事件2b00缺省值统计发送到 uring 与 uring_ext 两个通道的事件5. ch按 NoC 事务通道过滤NoC PMU 支持用该选项过滤特定事务通道的计数当前支持的通道编码通道3b010Request 通道3b100Snoop 通道3b110Response 通道3b111Data 通道6. tt_en只统计带 tracetag 的事务若设置tt_enNoC PMU 只统计设置了 tracetag 的事务。tracetag 的详细机制即上文 tt_req/tt_core 部分所述。PMU v3identifier 0x40子 PMU 划分与 ext 选项PMU v3 的 identifier 为0x40。为了获得更细粒度的跟踪能力v3 把部分 uncore PMU 拆分为若干 part每个 part 拥有专属 PMU这些 PMU 合起来覆盖某个 uncore 设备的全部事件监控职责。sysfs 命名格式随之变化/sys/bus/event_source/devices/hisi_sccl{X}_l3c{Y}_{Z}/ddrc{Y}_{Z}/noc{Y}_{Z}其中Z是 sub-id表示同一硬件设备不同 part 对应的 PMU。不同 sub-id 的 PMU 用法基本一致特别地L3C PMU 提供了ext选项以探索更细粒度的 L3C 统计。驱动把ext作为向硬件下发 perf 命令时的“终止提示”取值约束为ext0缺省值可以直接使用事件名ext1与ext2必须使用事件码不支持事件名。文档给出的示例$# perf stat -a -e hisi_sccl0_l3c1_0/rd_spipe/ sleep 5或$# perf stat -a -e hisi_sccl0_l3c1_0/event0x1,ext1/ sleep 5其中hisi_sccl0_l3c1_0定位的是 SCCL 0 上 L3 缓存 1 的 pipe0。第一条命令因为隐含ext0定位到 L3C 的第一个 part第二条命令则对 L3C 的另一个 part 以事件0x1发起计数。源码与文档完全对应hisi_get_ext()从config:16-17提取 ext 值hisi_uncore_l3c_pmu.c 及 v3 format 组。在hisi_l3c_pmu_get_event_idx()hisi_uncore_l3c_pmu.c中普通事件与扩展事件分别在不同的计数器位段中分配索引并把对应的基地址base或ext_base[ext - 1]保存到event-hw.event_base——因为普通事件和扩展事件位于不同的地址空间。probe 阶段hisi_uncore_l3c_pmu.c若检测到硬件支持 ext则按中断数量推算 ext 区域数并累加计数器总数因此 v3 的 L3C 最多可监视 23 倍于单区域数量的并发事件。按 CCL/ICL ID 过滤srcid/tgtidv3 下用户还可通过srcid_cmd srcid_msk配置只统计来自特定 CCL/ICL 的数据通过tgtid_cmd tgtid_msk统计发往特定 CCL/ICL 的数据。注意掩码语义srcid_msk/tgtid_msk中置 1 的位表示匹配时不检查该位。若上述所有过滤选项都未启用PMU 按缺省值工作——不区分过滤条件与 ID 信息直接返回 PMU 计数器中的总计数。功能限制不支持采样与 per-task 绑定文档明确当前驱动不支持采样因此perf record不可用由于事件全部属于 uncoreattach 到具体 task 也不被支持。源码在 hisi_uncore_pmu.c 的hisi_uncore_pmu_event_init()中给出了硬性校验采样事件或带PERF_ATTACH_TASK的事件直接返回-EOPNOTSUPP注释解释了原因计数器为 CPU dieSCCL内所有核共享且 uncore 计数器不隶属于任何 CPU无法支持 per-task 模式event-cpu 0未指定 CPU返回-EINVAL事件组内的硬件事件数不得超过 PMU 可用计数器数hisi_validate_event_group()事件码超过该 PMU 的check_event上限返回-EINVAL。例如 L3C v1 上限为0x59L3C_V1_NR_EVENTSv2/v3 为0xFF。另外从驱动结构看公共头文件定义了HISI_MAX_COUNTERS为0x1824即单个 PMU 事件最多可挂 24 个硬件计数器L3C 每个区域固定 8 个计数器L3C_NR_COUNTERS。计数精度方面L3C v1 为 48 位计数器v2/v3 为 64 位这由各版本的hisi_pmu_dev_info中的counter_bits字段声明hisi_uncore_l3c_pmu.c。公共框架的hisi_uncore_pmu_set_event_period()hisi_uncore_pmu.c会把回绕点设为2^(counter_bits - 1)为极端情况下的中断延迟留出余量。小结与深入路径设备发现/sys/bus/event_source/devices/hisi_sccl*_{l3c,hha,ddrc}*目录下的events/、format/、cpumask、associated_cpus、identifier属性是理解每个 PMU 能力的权威入口perf list是其用户态映射事件统计优先perf stat -a -e pmu/event/ sleep N需要精细过滤时按 v2/v3 的tt_core、tt_req、datasrc_cfg/datasrc_skt、ch、tt_en、ext、srcid/tgtid组合使用事件名最稳妥ext ! 0除外原始config0xNN编码需与format/属性及驱动中的事件表核对由于不支持采样与 per-task 绑定本套 PMU 适合做系统级-a带宽、命中率、延迟来源类的统计性剖析而非逐样本的火焰图分析源码入口公共框架 hisi_uncore_pmu.c 与 hisi_uncore_pmu.hL3C 实现 hisi_uncore_l3c_pmu.cHHA/DDRC 等其余模块见 drivers/perf/hisilicon/L3C 的 ACPI 设备 ID 为 HISI0213v1、HISI0214v2、HISI0215v3可用于在 ACPI 系统中确认硬件版本hisi_uncore_l3c_pmu.c文档最后提示如需特定 SoC 上 PMU 设备的完整事件清单及其信息建议联系驱动维护者获取。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门