ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux 内核 ali_drw PMU 驱动深度解析:Yitian 710 DDR Driveway 非核性能监控与带宽测量

Linux 内核 ali_drw PMU 驱动深度解析:Yitian 710 DDR Driveway 非核性能监控与带宽测量 Linux 内核 ali_drw PMU 驱动深度解析Yitian 710 DDR Driveway 非核性能监控与带宽测量【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux本文基于 Linux 内核文档 Documentation/admin-guide/perf/alibaba_pmu.rst 展开聚焦阿里巴巴平头哥T-HeadYitian 710 SoC 的 DDR 子系统 DrivewayDRW非核性能监控单元uncore PMU它如何为 16 个 DDR5 子通道提供 36 路硬件计数器、内核驱动 alibaba_uncore_drw_pmu.c 如何将其接入 perf 框架以及如何用perf stat和 metric 实测 DDR 读写带宽。读完本文你可以掌握该 PMU 的寄存器组织、事件编码规则、完整的 perf 使用命令、带宽计算公式以及驱动在 probe、中断、CPU 热插拔等环节的源码级实现细节。硬件背景Yitian 710 的 DDR5 内存子系统与 DRW PMUYitian 710 是由阿里巴巴芯片业务部门平头哥自研的服务器 SoC内核为它实现了非核 PMU用于性能分析、功能调试与系统维护。内存侧硬件结构决定了 PMU 的组织方式Yitian 710 共有8 条 DDR5/DDR4 通道每颗 die双 die 封装各承载 4 条通道之间相互独立各自处理系统内存请求每条 DDR5 通道又被拆分为2 个独立的子通道sub-channel因此整机共 16 个子通道DDR Sub-System Driveway 为每个子通道配备一个独立的 PMU用于监视各类性能指标。Driveway PMU 在 perf 中的设备命名规则为ali_drw_sys_base_addr其中地址段取 MMIO 基址右移 12 位后的十六进制值。原文档给出的实例ali_drw_21000与ali_drw_21080die 0 上同一 DDR 通道的两个子通道die 1 的 PMU 设备名前缀为ali_drw_400XXXXX例如ali_drw_40021000。每个子通道的 PMU 共有36 个计数器划分为四个组分组名称计数器数量用途Group 0PMU Cycle Counter1 对高 24 位 低 32 位拼接基于 DDRC 核心时钟的周期计数Group 1PMU Bandwidth Counters8统计所选 rank 中 8 个 bank group 的总访问量或由前 4 个计数器分别统计 4 个 rank基本传输单位为 64BGroup 2PMU Retry Counters10统计各类不可纠正错误uncorrectable error的重试次数Group 3PMU Common Counters16统计通用事件需要注意当前 Driveway PMU 驱动只使用 Group 0周期计数器和 Group 316 个通用计数器带宽与重试计数器尚未暴露给 perf 事件层。在信号链上DDR 控制器DDRCTL与 DDR PHY 共同构成 SoC 总线到 DDR 存储器的完整通路DDRCTL 接收由 Synopsys 自定义的主机接口HIF事务在内部排队并按 SDRAM 时序、事务优先级和事务间依赖进行调度再通过 DFI 接口向 PHY 下发命令由 PHY 完成与 SDRAM 之间的数据收发。Driveway PMU 的硬件逻辑正是挂在 HIF、DFI 等关键信号上采集统计与性能日志。驱动如何接入 Linux perf 框架构建与匹配方式该功能由 Kconfig 选项CONFIG_ALIBABA_UNCORE_DRW_PMU控制见 drivers/perf/Kconfigconfig ALIBABA_UNCORE_DRW_PMU tristate Alibaba T-Head Yitian 710 DDR Sub-system Driveway PMU driver depends on (ARM64 ACPI) || COMPILE_TEST help Support for Driveway PMU events monitoring on Yitian 710 DDR Sub-system.编译规则在 drivers/perf/Makefile 中obj-$(CONFIG_ALIBABA_UNCORE_DRW_PMU) alibaba_uncore_drw_pmu.o。适用前提由此明确生产环境需要ARM64 ACPI平台Yitian 710 通过 ACPI 描述硬件编译测试则放开给任意架构。驱动是标准的 platform 驱动通过 ACPI HID 匹配设备见 alibaba_uncore_drw_pmu.c/* * Due to historical reasons, the HID used in the production environment is * ARMHD700, so we leave ARMHD700 as Compatible ID. */ static const struct acpi_device_id ali_drw_acpi_match[] { {BABA5000, 0}, {ARMHD700, 0}, {} };源码注释说明生产固件历史原因沿用了 HIDARMHD700因此两个 HID 同时保留以兼容存量机器。probe 流程命名、复位与 PMU 注册probe 函数 ali_drw_pmu_probe 完成以下工作映射寄存器空间devm_platform_get_and_ioremap_resource(pdev, 0, res)取第 0 号资源并 ioremap生成 PMU 名称kasprintf(ali_drw_%llx, res-start ALI_DRW_PMU_PA_SHIFT)其中ALI_DRW_PMU_PA_SHIFT为 12。这与文档中ali_drw_21000、ali_drw_40021000等命名规则完全对应——设备名就是 MMIO 基址的十六进制硬件复位与中断使能向ALI_DRW_PMU_CNT_CTRL写CNT_RST复位全部计数器向溢出中断使能寄存器写入通用计数器掩码并清除残留中断状态绑定亲和 CPUdrw_pmu-cpu smp_processor_id()记录 IRQ 所在首选 CPU初始化 IRQ并调用perf_pmu_register()将 PMU 注册进 perf 框架填充struct pmu回调表event_init/add/del/start/stop/read并声明task_ctx_nr perf_invalid_context、capabilities PERF_PMU_CAP_NO_EXCLUDE——前者从结构上声明该 PMU 不支持任务上下文详见下文限制小节。寄存器地图驱动顶部集中定义了 Driveway PMU 的寄存器布局相对子通道 MMIO 基址的偏移偏移宏定义作用0xC00ALI_DRW_PMU_CNT_CTRL计数器全局控制CNT_STARTBIT(0)、CNT_STOPBIT(1)、CNT_RSTBIT(2)0xC04ALI_DRW_PMU_CNT_STATE计数器状态0xC08ALI_DRW_PMU_TEST_CTRL测试控制选择被预置计数器的编号0xC0CALI_DRW_PMU_CNT_PRELOAD计数器预置初值0xC10 / 0xC14ALI_DRW_PMU_CYCLE_CNT_HIGH/LOW周期计数器高 24 位掩码GENMASK(23,0)/ 低 32 位拼成 56 位周期值0xC68ALI_DRW_PMU_EVENT_SELn(n)事件选择寄存器0–3 号选择器按 4 字节步距排布每 32 位寄存器内 4 个计数器共享每个计数器占 8 位事件号 6 位 使能位CNT_ENBIT(7)0xC78ALI_DRW_PMU_COMMON_COUNTERn(n)16 个通用计数器4 字节步距0xCB8 / 0xCBCOV_INTR_ENABLE_CTL/DISABLE_CTL溢出中断使能/禁用0xCC0 / 0xCC4 / 0xCC8OV_INTR_ENABLE_STATUS / OV_INTR_CLR / OV_INTR_STATUS溢出中断状态与清除通用计数器占 bit[23:8]带宽计数器占 bit[7:0]关键宏定义见 alibaba_uncore_drw_pmu.c。事件选择寄存器采用“4 个计数器共用 32 位寄存器、每个计数器 8 位字段”的紧凑布局ali_drw_pmu_enable_counter 用shift 8 * (n % 4)定位字段后做读-改-写写入事件号并拉高使能位。事件编码与 sysfs 接口perf 用户通过config字段低 8 位config:0-7见 format 属性定义选择事件。驱动在 sysfsevents/目录下暴露了完整的事件表ali_drw_pmu_events_attrs可按语义归类HIF 事务类带宽测量核心事件名config含义hif_rd_or_wr0x0HIF 读或写命令hif_wr0x1HIF 写命令hif_rd0x2HIF 读命令hif_rmw0x3HIF 读改写RMW命令hif_hi_pri_rd0x4高优先级读DFI 数据类dfi_wr_data_cycles0x7、dfi_rd_data_cycles0x8。调度与拥塞类hpr_xact_when_critical0x9、lpr_xact_when_critical0xA、wr_xact_when_critical0xB、war_hazard/raw_hazard/waw_hazard0x17–0x19、visible_window_limit_reached_rd/wr0x30–0x31。*DRAM 操作类op_is_系列**op_is_activate0xC、op_is_rd_or_wr0xD、op_is_rd_activate0xE、op_is_rd0xF、op_is_wr0x10、op_is_mwr0x11、op_is_precharge0x12、precharge_for_rdwr0x13、precharge_for_other0x14、rdwr_transitions0x15、write_combine0x16、op_is_refresh0x2A、op_is_crit_ref0x2B、op_is_load_mode0x2D、op_is_zqcl0x2E、op_is_zqstart0x37、op_is_zqlatch0x38、op_is_tcr_mrr0x36等。Rank 级低功耗状态类op_is_enter_selfref_rk0–rk30x1A–0x1D、op_is_enter_powerdown_rk0–rk30x1E–0x21、selfref_mode_rk0–rk30x26–0x29。CHI 互联类chi_txreq0x39、chi_txdat0x3A、chi_rxdat0x3B、chi_rxrsp0x3C、tsz_vio0x3D。周期事件cycle0x80对应 Group 0 的 56 位周期计数器。用户空间可通过/sys/bus/event_source/devices/ali_drw_XXXX/events/查看事件定义、format/event查看编码位域、cpumask查看该 PMU 绑定的 CPU、identifier查看取值ali_drw_pmusysfs 属性组。事件生命周期与计数器分配initali_drw_pmu_event_init 校验 PMU 类型匹配随后向CNT_CTRL写CNT_RST复位全部计数器并把hwc-idx置为 -1 等待分配addali_drw_pmu_add 中非 cycle 事件通过 ali_drw_get_counter_idx 在 16 个通用计数器位图中test_and_set_bit抢占一个空闲计数器占满则返回-EBUSYcycle 事件无需计数器idx -1start/stopali_drw_pmu_start 对 cycle 事件仅置CNT_START通用事件则先经 ali_drw_pmu_event_set_period 写TEST_CTRL选中计数器编号、写CNT_PRELOAD预置初值当前恒为 0再配置事件选择寄存器并全局启动读取ali_drw_pmu_read_counter 对 cycle 事件读取高低两个寄存器拼成 56 位值对通用事件读 32 位计数器ali_drw_pmu_event_update 用 CAS 循环更新prev_count并按事件类型对delta分别做 56 位ALI_DRW_PMU_OV_INTR_MASK或 32 位ALI_DRW_CNT_MAX_PERIOD截断。溢出中断与 CPU 热插拔溢出中断处理函数 ali_drw_pmu_isr 的逻辑是先遍历该 IRQ 关联的所有 PMU 并禁用活动计数器读取OV_INTR_STATUS得到溢出位图对每个溢出计数器执行“更新累计值 → 重新预置周期 → 恢复使能”最后写OV_INTR_CLR清除状态位。两个值得注意的实现细节IRQ 共享源码中的 FIXME 注释L444-L449指出某个 DDRSS Driveway PMU 的溢出中断与 MPAM 的 ERR_IRQ 在硬件上共用同一中断号因此被迫以IRQF_SHARED注册注释同时表明 PMU 中断本不应与其他部件共享CPU 热插拔驱动注册了cpuhp状态机ali_drw_pmu_offline_cpu。当 IRQ 亲和的首选 CPU 下线时在同 NUMA 节点找不到则全局选择新目标 CPU调用perf_pmu_migrate_context()迁移该 PMU 上的 perf 上下文并更新 IRQ 亲和提示保证事件不因 CPU 下线而失效。实战用 perf 测量 DDR 带宽通过统计发送到 DDRC 的 HIF READ/WRITE/RMW 命令数即可计算带宽。文档 alibaba_pmu.rst 给出的完整示例对 die 0 的 4 条通道 × 每通道 2 个子通道共 8 个 PMU 同时统计hif_wr、hif_rd、hif_rmw、cycle四个事件perf stat \ -e ali_drw_21000/hif_wr/ \ -e ali_drw_21000/hif_rd/ \ -e ali_drw_21000/hif_rmw/ \ -e ali_drw_21000/cycle/ \ -e ali_drw_21080/hif_wr/ \ -e ali_drw_21080/hif_rd/ \ -e ali_drw_21080/hif_rmw/ \ -e ali_drw_21080/cycle/ \ -e ali_drw_23000/hif_wr/ \ -e ali_drw_23000/hif_rd/ \ -e ali_drw_23000/hif_rmw/ \ -e ali_drw_23000/cycle/ \ -e ali_drw_23080/hif_wr/ \ -e ali_drw_23080/hif_rd/ \ -e ali_drw_23080/hif_rmw/ \ -e ali_drw_23080/cycle/ \ -e ali_drw_25000/hif_wr/ \ -e ali_drw_25000/hif_rd/ \ -e ali_drw_25000/hif_rmw/ \ -e ali_drw_25000/cycle/ \ -e ali_drw_25080/hif_wr/ \ -e ali_drw_25080/hif_rd/ \ -e ali_drw_25080/hif_rmw/ \ -e ali_drw_25080/cycle/ \ -e ali_drw_27000/hif_wr/ \ -e ali_drw_27000/hif_rd/ \ -e ali_drw_27000/hif_rmw/ \ -e ali_drw_27000/cycle/ \ -e ali_drw_27080/hif_wr/ \ -e ali_drw_27080/hif_rd/ \ -e ali_drw_27080/hif_rmw/ \ -e ali_drw_27080/cycle/ -- sleep 10由于每个子通道 PMU 只有 16 个通用计数器且事件不能分组上述命令一次挂 32 个事件8 个 PMU × 4 事件仍在限额之内die 1 的 8 个子通道可同理按ali_drw_400XXXXX命名追加但需与 die 0 的事件分两批统计或依赖下文 metric。更简洁的方式是直接使用 perf 的 metric 机制。内核树在 tools/perf/pmu-events/arch/arm64/thead/yitian710/sys/metrics.json 中预置了两个 Yitian 710 专用指标{ MetricName: ddr_read_bandwidth.all, BriefDescription: The ddr read bandwidth(MB/s)., MetricGroup: ali_drw, MetricExpr: hif_rd * 64 / 1e6 / duration_time, ScaleUnit: 1MB/s, Unit: ali_drw, Compat: ali_drw_pmu }, { MetricName: ddr_write_bandwidth.all, BriefDescription: The ddr write bandwidth(MB/s)., MetricExpr: (hif_wr hif_rmw) * 64 / 1e6 / duration_time, ScaleUnit: 1MB/s, Unit: ali_drw, Compat: ali_drw_pmu }使用方式文档 L91-L94perf stat -M ddr_read_bandwidth.all -- sleep 10 perf stat -M ddr_write_bandwidth.all -- sleep 10带宽计算公式与物理含义文档给出的手工计算公式读带宽 perf_hif_rd * DDRC_WIDTH * DDRC_Freq / DDRC_Cycle写带宽 (perf_hif_wr perf_hif_rmw) * DDRC_WIDTH * DDRC_Freq / DDRC_Cycle其中DDRC_WIDTH 64 bytes对照 metrics.json 中的表达式hif_rd * 64 / 1e6 / duration_time两者等价DDRC_Freq / DDRC_Cycle正是 DDRC 核心时钟在采样窗口duration_time内的频率而 metric 用“64B 每次 HIF 事务 / 总时间”直接折算出 MB/s。从源码实现看这个 64B 与文档对 Group 1 计数器的描述一致“The base transfer unit is 64B”——每次 HIF 读写命令对应一次 64 字节基本传输单元cycle事件config 0x80读取的是 56 位 DDRC 周期计数器可作为分母精确换算频率。RMW 事件计入写带宽也符合 DDR 协议读改写操作最终产生写回故写侧统计取hif_wr hif_rmw。能力边界与适用限制文档 L103-L105 明确声明的限制均可在源码中找到对应实现不支持采样perf record 不可用ali_drw_pmu_event_init 中is_sampling_event()命中即打印 Sampling not supported! 并返回-EOPNOTSUPP。原因是计数器只统计总量、没有精确的事件时间戳无法提供采样所需的回抛scheduling信息不支持附加到任务由于事件全部是 uncore与具体 CPU 执行流无关驱动拒绝PERF_ATTACH_TASK-EOPNOTSUPP并把task_ctx_nr设为perf_invalid_context、在 event_init 中将event-cpu强制改为 PMU 绑定的 IRQ CPUL542-L546不支持硬件分组event_init 拒绝非软件事件的 group leader 及组内兄弟事件driveway only allow one event!即每个 perf 表达式项只能是单事件或软件事件组计数器配额每个子通道 PMU 最多同时统计 16 个非 cycle 通用事件Group 3 计数器上限超限返回-EBUSY。因此该 PMU 的定位是系统级内存带宽与 DRAM 行为统计配合perf stat做全局计数而非 CPU 级性能剖析需要采样式剖析时应结合 CPU PMU 使用。小结与延伸阅读本文梳理的 ali_drw PMU 是 Linux 内核中针对 Yitian 710 DDR 子通道的 uncore 监控能力硬件上每个 DDR5 子通道一个 PMU、36 计数器分 4 组软件上由 drivers/perf/alibaba_uncore_drw_pmu.c 以 ACPI platform 驱动方式接入 perf暴露 40 余个 HIF/DFI/DRAM/CHI 事件并通过 sysfs 事件表与 perf metricmetrics.json提供带宽测量。相关延伸阅读用户文档Documentation/admin-guide/perf/alibaba_pmu.rst索引页 Documentation/admin-guide/perf/index.rst驱动源码与 Kconfigdrivers/perf/alibaba_uncore_drw_pmu.c、drivers/perf/Kconfigperf 指标定义tools/perf/pmu-events/arch/arm64/thead/yitian710/sys/metrics.json。适用前提再强调一次该功能依赖 Yitian 710 硬件与描述 DRW 节点的 ACPI 固件HIDBABA5000/ARMHD700内核需开启CONFIG_ALIBABA_UNCORE_DRW_PMU在非 Yitian 710 平台上设备不会注册perf 中也看不到ali_drw_*设备。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表