# ls /sys/kernel/debug/bpmp/debug/actmon/ avg_band_freq avg_sustain_coef avg_window_log2 boost_down_coef boost_down_threshold boost_up_coef boost_up_threshold down_wmark_window enable mc_all_avg_activity mc_all_last_prd_activity sample_period up_wmark_window
cat /sys/kernel/debug/interconnect/interconnect_summary node tag avg peak -------------------------------------------------------------------- Memory Controller 7179000 21299200 17000000.gpu 0 0 0 290f000.admaif 0 0 393216 140a0000.pcie 0 250000 0 13800000.display 0 2743000 21299200 13e00000.host1x:vi1@14c00000 0 0 0 13e00000.host1x:vi0@15c00000 0 0 0 bc00000.rtcpu 0 0 0 15540000.nvjpg 0 0 0 15380000.nvjpg 0 0 0 15480000.nvdec 0 0 0 15340000.vic 0 0 0 141e0000.pcie 0 0 0 14160000.pcie 0 3936000 0 14100000.pcie 0 250000 0 cpu4 0 0 816000 cpu0 0 0 1632000 hdar 0 0 nvencsrd 0 0 pcie6ar 0 0 pcie6aw 0 0 pcie7ar 0 0 nvencswr 0 0 dla0rdb 0 0 dla0rdb1 0 0 dla0wrb 0 0 dla1rdb 0 0 pcie7aw 0 0 141e0000.pcie 0 0 0 pcie8ar 0 0 hdaw 0 0 pcie8aw 250000 0 140a0000.pcie 0 250000 0 pcie9ar 0 0 pcie6ar1 0 0 pcie9aw 0 0 pcie10ar 0 0 pcie10aw 0 0 pcie10ar1 0 0 pcie7ar1 0 0 mgbeard 0 0 mgbebrd 0 0 mgbecrd 0 0 mgbedrd 0 0 mgbeawr 0 0 mgbebwr 0 0 mgbecwr 0 0 sdmmcrab 0 0 mgbedwr 0 0 sdmmcwab 0 0 vicsrd 0 0 vicswr 0 0 15340000.vic 0 0 0 dla1rdb1 0 0 dla1wrb 0 0 vi2w 0 0 13e00000.host1x:vi1@14c00000 0 0 0 vi2falr 0 0 viw 0 0 13e00000.host1x:vi0@15c00000 0 0 0 nvdecsrd 0 0 nvdecswr 0 0 15480000.nvdec 0 0 0 aper 0 0 apew 0 0 vi2falw 0 0 nvjpgsrd 0 0 nvjpgswr 0 0 15380000.nvjpg 0 0 0 nvdisplayr 0 0 bpmpr 0 0 bpmpw 0 0 bpmpdmar 0 0 bpmpdmaw 0 0 apedmar 0 0 apedmaw 0 393216 290f000.admaif 0 0 393216 nvdisplayr1 2743000 21299200 13800000.display 0 2743000 21299200 vifalr 0 0 vifalw 0 0 dla0rda 0 0 dla0falrdb 0 0 dla0wra 0 0 dla0falwrb 0 0 dla1rda 0 0 dla1falrdb 0 0 dla1wra 0 0 dla1falwrb 0 0 rcer 0 0 rcew 0 0 bc00000.rtcpu 0 0 0 pcie0r 0 0 pcie0w 0 0 pcie1r 0 0 pcie1w 250000 0 14100000.pcie 0 250000 0 pcie2ar 0 0 pcie2aw 0 0 pcie3r 0 0 pcie3w 0 0 pcie4r 0 0 pcie4w 3936000 0 14160000.pcie 0 3936000 0 pcie5r 0 0 pcie5w 0 0 dla0rda1 0 0 dla0rda1 0 0 pcie5r1 0 0 nvjpg1srd 0 0 nvjpg1swr 0 0 15540000.nvjpg 0 0 0 sw_cluster0 0 13056000 cpu0 0 0 1632000 sw_cluster1 0 6528000 cpu4 0 0 816000 sw_cluster2 0 0 nvl1r 0 0 nvl1w 0 0 17000000.gpu 0 0 0 External Memory Controller 0 0 17000000.gpu 0 0 0 290f000.admaif 0 0 393216 140a0000.pcie 0 250000 0 13800000.display 0 2743000 21299200 13e00000.host1x:vi1@14c00000 0 0 0 13e00000.host1x:vi0@15c00000 0 0 0 bc00000.rtcpu 0 0 0 15540000.nvjpg 0 0 0 15380000.nvjpg 0 0 0 15480000.nvdec 0 0 0 15340000.vic 0 0 0 141e0000.pcie 0 0 0 14160000.pcie 0 3936000 0 14100000.pcie 0 250000 0 cpu4 0 0 816000 cpu0 0 0 1632000 External Memory (DRAM) 0 0 17000000.gpu 0 0 0 290f000.admaif 0 0 393216 140a0000.pcie 0 250000 0 13800000.display 0 2743000 21299200 13e00000.host1x:vi1@14c00000 0 0 0 13e00000.host1x:vi0@15c00000 0 0 0 bc00000.rtcpu 0 0 0 15540000.nvjpg 0 0 0 15380000.nvjpg 0 0 0 15480000.nvdec 0 0 0 15340000.vic 0 0 0 141e0000.pcie 0 0 0 14160000.pcie 0 3936000 0 14100000.pcie 0 250000 0 cpu4 0 0 816000 cpu0 0 0 1632000
root@ubuntu:~# cat /sys/kernel/debug/bpmp/debug/bwmgr/bw_request_status ID |Niso BW |Iso BW | Floor BW 0 |0 |0 |0 1 |0 |0 |0 2 |0 |0 |13056000 3 |0 |0 |6528000 4 |0 |0 |0 5 |0 |0 |0 6 |0 |0 |2889600 7 |0 |2743000 |21299200 8 |0 |0 |0 9 |0 |0 |0 10 |0 |0 |0 11 |250000 |0 |6528000 12 |0 |0 |0 13 |0 |0 |0 14 |3936000 |0 |44000000 15 |0 |0 |0 16 |0 |0 |0 17 |0 |0 |0 18 |250000 |0 |6528000 19 |0 |0 |0 20 |0 |0 |0 21 |0 |0 |0 22 |0 |0 |0 23 |0 |0 |0 24 |0 |0 |0 25 |0 |0 |0 26 |0 |0 |0 27 |0 |0 |0 28 |0 |0 |0 29 |0 |0 |0 30 |0 |0 |0 31 |0 |0 |0 32 |0 |0 |0 33 |0 |0 |0 34 |0 |0 |0 35 |0 |0 |0 36 |0 |0 |0 37 |0 |0 |393216 38 |0 |0 |0 39 |0 |0 |0 40 |0 |0 |0 41 |0 |0 |0 42 |0 |0 |0 43 |0 |0 |0 44 |0 |0 |0 45 |0 |0 |0 46 |0 |0 |0 Iso Rate Min (KHz) : 665000 Total Rate Min (KHz) : 665000 LA Rate Floor (KHz) : 665000 ISO Client Only Rate (KHz) : 5 Max Floor BW (Kbps) : 44000000
root@ubuntu:~# cat /sys/kernel/debug/bpmp/debug/actmon/boost_up_threshold 19194
BPMP BWMGR 是整个系统 DDR 带宽 QoS 的中央仲裁器。它接收来自内核驱动(GPU、Display、VIC、PCIe 等)和固件(如 RCE)的带宽请求,然后决定 EMC 时钟的最小频率(floor frequency),确保满足 QoS 需求,同时结合 actmon 利用率动态调整。
Iso Rate Min (KHz): 665000 → 等时(实时/低延迟)带宽请求导致的最小 EMC 频率 = 665 MHz Total Rate Min (KHz): 665000 → 所有带宽请求(Niso + Iso + Floor)聚合后的最小 EMC 频率 = 665 MHz LA Rate Floor (KHz): 665000 → 可能指 Latency-Aware(延迟敏感)的最低地板频率,也为 665 MHz ISO Client Only Rate (KHz): 5 → 纯 Iso 客户端贡献的极小频率增量(几乎忽略不计) Max Floor BW (Kbps): 44000000 → 当前所有 Floor BW 中的最大值 = 44 MB/s(来自 ID 14)
总体架构与设计原则BPMP 角色:BPMP 是一个独立的低功耗 ARM Cortex-M7 处理器,运行固件,负责 SoC(System on Chip)的电源、时钟和 QoS 管理。BWMGR 是 BPMP 固件中的一个服务模块,通过 MRQ(Message Request Queue)接口接收内核驱动(e.g., GPU、Display、PCIe)的带宽请求。请求以 Kbps(千比特每秒)为单位,BPMP 内部转换为 EMC 时钟频率(KHz)。 核心目标:实现预测性 QoS 分配,确保实时(Iso)任务优先,同时兼顾非实时(Niso)负载。设计原则包括:非侵入性:最小化内核开销,所有决策在 BPMP 固件中完成。 实时性:响应时间 <1ms,支持突发负载。 功耗优化:结合 actmon(Activity Monitor)监控,只在需要时提升 EMC 频率。
硬件依赖:依赖 EMC 控制器(管理 DDR 时钟)和 actmon 硬件单元(实时测量 DDR 利用率)。EMC 频率表预定义在设备树(DTB)中,例如 Orin Nano 的范围从 665 MHz 到 ~3200 MHz(Super Mode 下更高)。
请求类型 描述 适用场景 处理逻辑 Iso BW 伊索 BW 等时带宽(Isolated Bandwidth),优先级最高,确保低延迟和固定吞吐。 实时任务,如显示、视频解码、相机。 BPMP 隔离分配,求和所有 Iso 请求,选择能覆盖总 Iso BW 的最高 EMC 频率。 Niso BW 非等时带宽(Non-Isolated Bandwidth),平均带宽需求,不保证延迟。 非实时计算,如后台处理、AI 推理。 求和所有 Niso 请求,作为总带宽的一部分,与 Iso 结合计算 EMC 频率下限。 Floor BW 楼层 BW 区 地板带宽(Floor Bandwidth),最小保证带宽,用于峰值保护。 突发负载场景,如 PCIe 数据传输。 取所有 Floor 请求中的最大值,作为 EMC 频率的硬下限,确保不低于此带宽。

请求发送实现:内核驱动计算带宽(e.g., 显示驱动基于分辨率 × FPS × 比特深度),通过 clk_set_rate() 或类似 API 发送到 BPMP。BPMP 使用 BPC(Bytes Per Cycle,字节/周期)转换因子将 BW 映射到频率:freq = BW / (BPC × bus_width × efficiency)(bus_width 如 64-bit,efficiency ~80%)。
频率决策:使用预定义频率表(DTB 中的 ucf-soc-mapping)选择最低能满足总需求的 EMC setpoint。算法优先 Iso(实时),然后 Floor(峰值保护),最后 Niso(平均)。示例:如果 Max Floor BW = 44 MB/s(如你的 ID 14),BPMP 计算所需 freq = (44e6 / 8) / BPC ≈ 665 MHz(最低点)。
输出指标解释(参考你的数据):Iso Rate Min: 基于 sum(Iso BW) 的最小频率(你的 665 MHz)。 Total Rate Min: 整体聚合频率。 Max Floor BW: 直接取 max(Floor),影响地板决策。
实现细节:固件中使用链表或数组存储请求,聚合为 O(n) 操作(n=客户端数,小于 50)。变化时通过通知更新 EMC。
Actmon 监控:中央 actmon (mc_all) 硬件实时采样 DDR 利用率(%),BPMP 每隔固定周期(e.g., 10ms)比较阈值,实现闭环控制。配置:通过 DTB 设置阈值(e.g., boost_up_threshold = 0x1e,表示 30%)。 算法:滞后(hysteresis)机制避免频繁切换(e.g., 需持续超过阈值 X 周期才调整)。
交互流程:客户端请求 → BWMGR 聚合 → 设置 EMC min_rate。 Actmon 采样利用率 → 与阈值比较 → BPMP 调整 EMC rate(如果超出 min_rate)。 反馈循环:确保 QoS 不被违反。
调试接口:你的命令(如 bw_request_status)暴露聚合状态,支持实时监控和手动锁定(mrq_rate_locked)。 潜在挑战:高负载下聚合延迟(固件优化为微秒级);兼容性依赖 JetPack 版本(r36.3+)。
总体而言,BWMGR 通过聚合请求和监控反馈实现了高效的 DDR QoS 调控,比早期 PM QoS 更硬件化,更适合高性能嵌入式系统。如果需要源代码级分析(e.g., BPMP 固件逆向),或针对你的数据进一步诊断,我可以提供更多指导。
核心概念:为什么需要滞后机制?EMC 频率切换不是免费的:涉及电压调整、PLL 重新锁定、时钟门控等操作,切换太频繁会导致功耗 spikes、延迟抖动,甚至稳定性问题。 内存带宽利用率(utilization,由 central actmon 硬件实时采样)天然会小幅波动(噪声)。 如果没有滞后,utilization 在阈值附近振荡 → EMC 频率反复升降 → 坏用户体验。 滞后机制创建了一个“缓冲区”:只有当利用率显著超过/低于阈值时才触发调整。
关键阈值配置(来自 BPMP 设备树)这些值在 BPMP 的 Device Tree Blob (DTB) 中定义,通常位于 bwmgr { cactmon { mc_all { ... } } } 节点下:
bwmgr { enabled = <0x1>; cactmon { enabled = <0x1>; mc_all { boost_up_threshold = <0x1e>; // 30% (十六进制 0x1e = 30) boost_down_threshold = <0x14>; // 20% (十六进制 0x14 = 20) // 其他参数如采样周期等 }; }; };
boost_up_threshold:上阈值(默认 30%),利用率超过此值 → 考虑升频。 boost_down_threshold:下阈值(默认 20%),利用率低于此值 → 考虑降频。 死区范围:20% ~ 30%(默认 10% 宽度),这个区间内 不触发任何频率调整。
读取当前 EMC 频率状态(是否已经在某个频率点运行)。
比较逻辑(带滞后):如果当前 EMC 频率 已经处于“高”状态(最近是升频触发的):只有当 current_util < boost_down_threshold(< 20%)时,才允许 降频。 如果 20% ≤ current_util ≤ 30%,保持当前频率(死区保护)。
如果当前 EMC 频率 已经处于“低”状态(最近是降频或初始状态):只有当 current_util > boost_up_threshold(> 30%)时,才允许 升频。 如果 20% ≤ current_util ≤ 30%,保持当前频率。
这就是典型的施密特触发器(Schmitt Trigger)式滞后:升频阈值:30% 降频阈值:20% 形成 10% 的滞后窗口,避免边界振荡。
结合 BWMGR 的 QoS 请求:BWMGR 先根据客户端的 Iso/Niso/Floor BW 请求计算一个 最小频率下限(Total Rate Min)。 actmon DFS 只在 当前频率低于 QoS 下限 时强制升频,或在 利用率低 + QoS 允许 时降频。 滞后机制只作用于 actmon 驱动的动态调整部分,不影响 QoS 硬下限。
额外保护机制(NVIDIA 文档中隐含):持续计数:有些实现要求利用率连续超过阈值 N 个采样周期才触发(避免瞬时尖峰)。 最小保持时间:频率切换后可能有最小驻留时间(类似 thermal governor 的 polling-delay-passive)。 block_window(类似 VIC actmon 的机制):防止过于频繁的决策。
BWMGR 将带宽请求明确分为三种类型,并赋予不同的优先级和处理规则:Iso BW(等时带宽 / Isochronous Bandwidth): 专为实时、低抖动任务设计,优先级最高。 典型客户端:Display Controller、相机(CSI)、某些媒体引擎(VIC/NVDEC 在实时模式下)。 特点:需要固定、周期性的带宽保证,不能被抢占或延迟。 Floor BW(地板带宽): 峰值保护下限,用于突发或硬实时任务,确保最小保证带宽。 Niso BW(非等时带宽 / Non-Isolated Bandwidth): 普通平均带宽请求,优先级最低,适用于 GPU 计算、AI 推理、后台任务等非实时负载。
保证机制: BWMGR 在聚合时先满足 Iso BW,再考虑 Floor BW,最后才叠加 Niso BW。
Total Rate Min(最终 EMC 频率下限)计算公式大致为:
freq_min = max( f(Iso_sum), f(Floor_max), f(Niso_sum + Iso_sum + Floor_max) )
其中 f() 是带宽到频率的映射函数(预定义表 + 效率因子)。
这意味着即使 Niso 负载很高,只要 Iso 需求不高,EMC 频率也不会无限制上升;反之,Iso 需求会强制推高频率下限。
Iso BW 的隔离与硬保证隔离分配:Iso BW 是独立计算的,不与其他类型简单相加。BPMP 会选择一个频率点,使其总可用带宽 ≥ sum(Iso BW),即使这会导致整体利用率不高,也要优先满足。
硬下限:一旦 Iso 客户端发送请求,BPMP 会立即设置 EMC min_rate 为能覆盖该 Iso 总量的频率点。这个 min_rate 是硬约束,actmon DFS(动态调整)不能将其降下去。
示例:在你的 bw_request_status 中,Iso Rate Min = 665000 KHz,即使 Total Rate Min 也受其影响;如果 Iso BW 上升到需要 2GHz,EMC 就会被强制抬高。
非 Iso 客户端无法抢占:论坛中明确提到 PCIe 等非 Iso 客户端无法优先于 Iso 任务,也无法降低 Iso 延迟。这证明了硬件/固件层面的优先级隔离。
与 actmon DFS 的协作(滞后机制不影响 Iso 保证)actmon 驱动的动态升降频只在 QoS 下限之上起作用: 如果 QoS(主要是 Iso + Floor)已经把 EMC 推到较高频率 → actmon 利用率低时可以降,但绝不会低于 QoS min_rate。
如果当前频率已满足 Iso 需求 → actmon 利用率高时可以进一步升频(boost),但不会降到违反 Iso。
滞后窗口(boost_up/down threshold)主要防止非实时负载的抖动,对 Iso 的硬保证没有负面影响。
硬件层面的支持(MC / Memory Controller)Orin 的内存控制器(MC)本身支持QoS 仲裁和优先级队列。 Iso 流量通常映射到高优先级通道(或虚拟通道),在 DDR 总线争用时优先调度。 这与软件层 BWMGR 配合:BWMGR 确保总带宽足够,MC 确保 Iso 包的低延迟通过。
实际保证效果总结低延迟保证:Iso 任务的带宽需求被预留并优先调度,典型延迟抖动在微秒级(远优于非实时任务)。
无饥饿:即使 GPU 等 Niso 客户端请求 100+ GB/s,只要 Iso 需求是 5 GB/s,系统也会优先满足 Iso(频率至少到能覆盖 5 GB/s 的点)。
典型场景: 运行 4K 显示 + 相机捕获 → Display 和 CSI 的 Iso BW 被优先满足,EMC 频率被推高。
同时跑大模型推理(GPU Niso 高负载)→ GPU 只能使用剩余带宽,不会饿死显示/相机。
局限性与注意Iso BW 不是无限的:总 Iso 预留通常有上限(历史平台如 TX2 相机 Iso 限制在 10% 左右,Orin 可能更高但仍有限制)。
非 Iso 客户端(如 PCIe)无法变成 Iso,无法享受同等保证(NVIDIA 官方确认)。
如果 Iso 总需求超过硬件能力,会出现“iso bandwidth not available”错误(旧平台常见,Orin 较少但仍可能)。
总结:BWMGR 通过类型优先级 + Iso 独立计算 + 硬 min_rate + MC 硬件仲裁的多层机制,确保高实时任务的 DDR 带宽需求得到优先、稳定、硬保证,这正是其在嵌入式实时系统(如你的金融高性能应用)中取代旧 PM QoS 的核心原因。如果你有特定实时任务(如显示或相机)的 bw_request_status 输出,我可以帮你验证 Iso 是否被正确优先满足。

核心驱动文件:drivers/media/platform/tegra/tegra_camera_ctrl.c(或类似 tegra-vi / tegra-csi 模块) drivers/memory/tegra/tegra234.c(MC/ICC 提供者,处理 BPMP MRQ)
像素速率 (pixel_rate):pixel_rate = width × height × fps 单位:像素/秒 示例:3840 × 2160 × 30 = ≈ 248,832,000 像素/秒
每像素比特数 (bits_per_pixel 或 min_bits_per_pixel):来自传感器输出格式(设备树或 V4L2 fmt) 示例:RG10 (10-bit RAW) → 10 bits/pixel;YUV420 → 12 bits/pixel 等 设备树中常见:min_bits_per_pixel = <10>;
VI 峰值字节/像素 (vi_peak_byte_per_pixel):VI 单元(Video Input)处理时的最大字节/像素(考虑打包、padding、对齐) 设备树中常见:vi_peak_byte_per_pixel = <2>;(2 字节/像素,常用于 10/12-bit RAW 打包成 16-bit)
带宽裕度 (vi_bw_margin_pct):预留百分比裕度,防止突发抖动或多路复用 设备树中常见:vi_bw_margin_pct = <25>;(25% 裕度)
总 CSI 通道数与效率:num_csi_lanes(e.g., 4 lanes) max_lane_speed(e.g., 2.5 Gbps/lane) 效率因子(overhead 如 packet headers、deskew 等)通常隐含在裕度中
最终计算示例(简化,基于常见 4K@30fps RAW10):pixel_rate = 3840 × 2160 × 30 ≈ 249 Mpixel/s bits_per_pixel = 10 vi_peak_byte_per_pixel = 2(打包成 16-bit) vi_bw_margin_pct = 25% 原始带宽 = 249M × 10 bits × 2 bytes/bit / 8 bits/byte ≈ 622.5 MB/s 加裕度:622.5 × 1.25 ≈ 778 MB/s 转换为 Kbps:778 × 8 × 1024 ≈ 6,380,544 Kbps(≈ 6.38 Gbps) 但实际请求会映射到 KBps(论坛中常见 232031 KBps 等值),并取整/保守。
驱动中会进一步调整为 平均 BW(Niso)和 峰值 BW(Floor/Iso),Iso BW 通常取峰值部分。
BPMP 侧:接收 MRQ_BWMGR 请求(CMD_BWMGR_REQUEST_BW 或类似)。 聚合到对应客户端 ID(相机通常 ID 7~8 附近,或 VI 相关)。 Iso BW:用于实时保证(硬下限)。 Floor BW:用于峰值保护。 更新 Total Rate Min → 强制 EMC min_rate。
错误处理:如果请求失败(如总需求超硬件上限),打印如:
bwmgr req failed for 8 tegra_camera_isomgr_request: ICC failed to reserve 232031 KBps
这在 Orin NX 上常见(带宽上限低于 AGX),表示 BPMP 拒绝了请求。
nvidia,tegra-camera-platform { num_csi_lanes = <4>; // 总 CSI lanes max_lane_speed = <2500000>; // Kbit/s per lane min_bits_per_pixel = <10>; // 最小 bits/pixel vi_peak_byte_per_pixel = <2>; // VI 峰值 byte/pixel vi_bw_margin_pct = <25>; // VI 裕度 % // isp_peak_byte_per_pixel / isp_bw_margin_pct (如果有 ISP 处理) };