海思 PCIe 性能监控单元 (PMU)

在 Hip09 上,海思 PCIe 性能监控单元 (PMU) 可以监控 PCIe 的带宽、延迟、总线利用率和缓冲区占用数据。

每个 PCIe 核心都有一个 PMU,用于监控该 PCIe 核心的多个根端口(Root Port)以及这些根端口下游的所有端点(Endpoint)。

海思 PCIe PMU 驱动程序

PCIe PMU 驱动程序会注册一个名为其 sicl-id 和 PCIe 核心 id 的 perf PMU。

/sys/bus/event_source/hisi_pcie<sicl>_core<core>

PMU 驱动程序在 sysfs 中提供了可用事件和过滤选项的说明,请参阅 /sys/bus/event_source/devices/hisi_pcie<sicl>_core<core>。

“format” 目录描述了 perf_event_attr 结构体中 config(事件)和 config1(过滤选项)字段的所有格式。“events” 目录描述了 perf list 中显示的所有已记录事件。

“identifier” sysfs 文件允许用户识别 PMU 硬件设备的版本。

“bus” sysfs 文件允许用户获取 PMU 监控的根端口的总线号。此外,用户可以分别从 “bdf_min” 和 “bdf_max” sysfs 属性中获取 [bdf_min, bdf_max] 范围内的根端口。

perf 的使用示例

$# perf list
hisi_pcie0_core0/rx_mwr_latency/ [kernel PMU event]
hisi_pcie0_core0/rx_mwr_cnt/ [kernel PMU event]
------------------------------------------

$# perf stat -e hisi_pcie0_core0/rx_mwr_latency,port=0xffff/
$# perf stat -e hisi_pcie0_core0/rx_mwr_cnt,port=0xffff/

相关事件通常用于计算带宽、延迟或其他指标。它们需要同时开始和结束计数,因此相关事件最好在同一个事件组中使用,以获得预期的值。有两种方法可以判断它们是否为相关事件

  1. 通过事件名称,例如延迟事件 “xxx_latency, xxx_cnt” 或带宽事件 “xxx_flux, xxx_time”。

  2. 通过事件类型,例如 “event=0xXXXX, event=0x1XXXX”。

perf 组的使用示例

$# perf stat -e "{hisi_pcie0_core0/rx_mwr_latency,port=0xffff/,hisi_pcie0_core0/rx_mwr_cnt,port=0xffff/}"

当前驱动程序不支持采样。因此不支持 “perf record”。此外,PCIe PMU 也不支持附加到任务(attach to a task)。

过滤选项

  1. 目标过滤 (Target filter)

    PMU 只能监控目标根端口下游或目标端点下游的流量性能。PCIe PMU 驱动程序为用户提供了 “port” 和 “bdf” 接口。请注意,这两个接口必须设置其中一个,并且这两个接口不支持同时使用。如果两者都已设置,则只有 “port” 过滤器有效。如果未设置 “port” 过滤器或显式设置为零(默认值),则 “bdf” 过滤器将生效,因为 “bdf=0” 意味着 0000:000:00.0。

    • port

      “port” 过滤器可用于所有 PCIe PMU 事件,通过配置 16 位位图 “port” 可以选择目标根端口。对于 AP 层事件可以选择多个端口,而对于 TL/DL 层事件只能选择一个端口。

      例如,如果目标根端口是 0000:00:00.0 (x8 通道),则应设置位图的第 0 位,port=0x1;如果目标根端口是 0000:00:04.0 (x4 通道),则设置第 8 位,port=0x100;如果同时监控这两个根端口,则 port=0x101。

      perf 的使用示例

      $# perf stat -e hisi_pcie0_core0/rx_mwr_latency,port=0x1/ sleep 5
      
    • bdf

      “bdf” 过滤器只能用于带宽事件,通过将 BDF 配置为 “bdf” 来选择目标端点。计数器仅统计目标端点请求的消息的带宽。

      例如,“bdf=0x3900” 意味着目标端点的 BDF 为 0000:39:00.0。

      perf 的使用示例

      $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,bdf=0x3900/ sleep 5
      
  2. 触发过滤 (Trigger filter)

    当 TLP 长度首次大于/小于触发条件时,事件统计开始。您可以通过写入 “trig_len” 来设置触发条件,并通过写入 “trig_mode” 来设置触发模式。此过滤器只能用于带宽事件。

    例如,“trig_len=4” 意味着触发条件为 2^4 DW,“trig_mode=0” 意味着当 TLP 长度 > 触发条件时开始统计,“trig_mode=1” 意味着当 TLP 长度 < 触发条件时开始统计。

    perf 的使用示例

    $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,trig_len=0x4,trig_mode=1/ sleep 5
    
  3. 阈值过滤 (Threshold filter)

    当 TLP 长度在指定范围内时,计数器进行计数。您可以通过写入 “thr_len” 来设置阈值,并通过写入 “thr_mode” 来设置阈值模式。此过滤器只能用于带宽事件。

    例如,“thr_len=4” 意味着阈值为 2^4 DW,“thr_mode=0” 意味着计数器在 TLP 长度 >= 阈值时计数,“thr_mode=1” 意味着在 TLP 长度 < 阈值时计数。

    perf 的使用示例

    $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,thr_len=0x4,thr_mode=1/ sleep 5
    
  4. TLP 长度过滤 (TLP Length filter)

    在计算带宽时,数据可以由 TLP 数据包的特定部分组成。您可以通过 “len_mode” 进行指定

    • 2’b00: 保留(请勿使用,因为其行为未定义)

    • 2’b01: TLP 载荷(payload)带宽

    • 2’b10: TLP 头部(header)带宽

    • 2’b11: TLP 载荷和头部带宽

    例如,“len_mode=2” 表示仅计算 TLP 头部带宽,“len_mode=3” 表示最终带宽数据由 TLP 头部和载荷组成。如果未指定,默认值为 2’b11。

    perf 的使用示例

    $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,len_mode=0x1/ sleep 5