ARTICLE DETAIL

资讯详情

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

RK3568 上 OpenBMC 性能优化与替代方案实战

RK3568 上 OpenBMC 性能优化与替代方案实战 1. 从一次真实的移植卡顿说起去年秋天我接手了一个工业网关项目主控选的是瑞芯微 RK3568四核 Cortex-A55 加 Mali-G52接口丰富、功耗控制得也不错跑 OpenBMC 做带外管理从架构上看是相当合适的搭配。第一版移植做完串口能出 log网口能通风扇能转看起来一切正常。但真正压到产线环境里跑了两周问题就藏不住了Web 界面点一个传感器页面要等三四秒才出数据IPMI 命令偶尔超时日志里时不时冒出soft lockup的告警。这时候我才意识到把 OpenBMC “跑起来”和让它“跑得好”完全是两码事。这篇内容就是接着上一阶段的移植工作往下讲重点放在RK3568 平台上 OpenBMC 的性能优化以及当原生方案在某些场景下确实顶不住时有哪些替代思路可以兜底。我会把设备树调优、内核裁剪、服务精简、内存与 IO 调度、启动时间压缩这些环节拆开讲也会聊到 EtherCAT 主站、OV5695/OV8858 摄像头这类外设接入时对系统资源的挤占问题。如果你正在用 RK3568 做 BMC、工业控制或者边缘网关并且已经过了“点亮”阶段开始被响应速度和稳定性折磨那这篇内容应该能帮你少走一些弯路。需要先说明一点下面提到的所有参数和配置都是基于我手上这块正点原子 RK3568 开发板以及自制的底板实测得出的不同厂商的核心板在电源域、DDR 时序、外设挂载上会有差异照搬之前建议先在小批量上验证。另外OpenBMC 的版本迭代很快我用的基线是基于 Linux 5.10 内核的较新一版老版本在服务管理机制上差别不小这点要留意。2. 性能瓶颈到底出在哪先定位再动手优化最忌讳的就是上来就改参数。我见过太多人一听说“性能优化”就先去关服务、调 governor结果折腾一圈发现瓶颈根本不在那儿。所以在动手之前得先把 RK3568 上 OpenBMC 的性能画像摸清楚。2.1 用数据说话三类典型瓶颈的识别方法在 RK3568 这种四核 A55 的平台上OpenBMC 的性能问题基本逃不出三类CPU 调度瓶颈、内存与 IO 瓶颈、启动阶段瓶颈。识别方法其实不复杂关键是养成先采集后分析的习惯。CPU 调度瓶颈最典型的信号是soft lockup和rcu_sched detected stalls。这类告警说明某个 CPU 核心被长时间占用调度器没法及时切换。我当时的做法是在串口终端里挂一个后台采样脚本每隔 5 秒抓一次/proc/loadavg和top -bn1的前 15 行连续跑 24 小时。结果发现负载并不高平均只有 0.3 左右但ksoftirqd的占用率偶尔会飙到 30% 以上这就指向了中断处理的问题而不是应用层算力不够。内存与 IO 瓶颈的表现更隐蔽。RK3568 一般配 2GB 或 4GB LPDDR4OpenBMC 本身吃不了多少内存但如果你同时挂了摄像头采集、EtherCAT 主站这类实时性要求高的任务内存带宽和 IO 等待就会成为瓶颈。判断方法是看/proc/meminfo里的Dirty和Writeback字段如果这两个值长期偏高说明有大量数据在往存储里刷这时候要么优化写入策略要么换更快的存储介质。启动阶段瓶颈相对好定位直接在dmesg里看时间戳就行。RK3568 的 U-Boot 到内核再到用户态正常应该在 15 到 25 秒之间完成。如果超过 40 秒基本可以确定是某个服务在启动时做了阻塞操作或者设备树里有节点探测超时。2.2 一个容易被忽略的坑DDR 频率与 governor 的联动这里要单独拎出来讲一个我在 RK3568 上踩过的坑。很多人调性能第一反应是把 CPU governor 设成performance这没错但 RK3568 的 DDR 频率是跟着 CPU 负载联动的。如果你只锁了 CPU 频率DDR 还在动态调频那在负载突增的瞬间内存带宽跟不上照样会卡。我的做法是在设备树里把 DDR 的 devfreq governor 也固定住或者在启动脚本里通过 sysfs 手动设置。具体路径是/sys/class/devfreq/dmc/governor把它从simple_ondemand改成performance。实测下来Web 界面的首屏渲染时间从 3.2 秒降到了 1.8 秒左右效果比单纯锁 CPU 频率明显得多。注意固定 DDR 频率会带来功耗上升如果你的设备是无风扇设计或者对温升敏感建议先做热仿真再决定是否长期开启。2.3 优化优先级排序先做收益高、风险低的性能优化不是把所有能调的都调一遍而是按投入产出比排序。我一般按这个顺序来内核配置裁剪去掉用不到的功能模块收益直接风险可控。设备树精简禁用未使用的外设节点减少探测时间。服务与启动项精简OpenBMC 默认带了不少用不上的服务关掉能省内存和启动时间。调度与频率策略调整governor、IO scheduler、中断亲和性。应用层优化Web 后端、D-Bus 调用频率等。前两步做完通常能拿到 60% 以上的性能提升而且不容易引入新问题。后面几步属于锦上添花但也要做尤其是调度策略对实时性任务影响很大。3. 内核与设备树层面的硬核调优这一层是性能优化的主战场也是最能体现 RK3568 平台特性的地方。OpenBMC 跑在 Linux 上内核怎么配、设备树怎么写直接决定了系统的基础性能上限。3.1 内核裁剪把用不到的都砍掉OpenBMC 默认的内核配置是面向通用 BMC 场景的里面塞了大量 RK3568 用不上的驱动和子系统。我的做法是基于defconfig做减法而不是从零开始加这样能保证核心功能不丢。具体砍掉的东西包括所有非 RK3568 的 ARM 平台支持、用不到的 filesystem比如 XFS、BtrfsBMC 场景 ext4 足够、多余的网络协议栈比如完整的 IPv6 如果不用可以裁掉、以及大量 USB 和 PCIe 的冗余驱动。裁剪完之后内核镜像从 18MB 降到了 9MB 左右启动时的模块加载时间少了将近 3 秒。这里有个细节要注意OpenBMC 的phosphor-*系列服务有些依赖特定的内核配置比如CONFIG_FANOTIFY、CONFIG_INOTIFY_USER裁剪的时候别一刀切建议先用scripts/diffconfig对比一下裁剪前后的差异确认没有把关键选项关掉。3.2 设备树精简RK3568 设备树的关键节点处理RK3568 的设备树文件通常比较大因为芯片本身外设多。但实际项目里很多节点是用不到的。我的原则是没接外设的控制器一律 disable接了但暂时不用的也先 disable等需要时再开。以我手上的板子为例i2c3、i2c4、spi1、uart5到uart8这些都没接东西全部在设备树里标成status disabled。别小看这一步每个被禁用的控制器能省下几十毫秒的探测时间加起来就是几百毫秒。另外pinctrl节点也要精简。RK3568 的 pinctrl 默认会把所有引脚都配一遍如果你只用了其中一部分可以在设备树里只保留实际用到的引脚配置。这个操作稍微麻烦一点需要对照原理图逐个确认但收益是实打实的。还有一个容易被忽略的点是thermal节点。RK3568 的温控策略默认比较激进温度稍微上来就降频。如果你的设备散热条件好可以适当放宽温控阈值或者干脆在设备树里把thermal-zones的trips温度调高几度。我一般会调到 85 度才触发降频实测在工业环境下稳定性没问题。3.3 启动时间压缩从 U-Boot 到用户态的每一秒启动时间是 BMC 的一个重要指标尤其是需要快速响应的场景。RK3568 上压缩启动时间我主要做了这几件事U-Boot 阶段关掉不必要的命令和驱动把bootdelay设成 0同时开启CONFIG_BOOTSTAGE来记录各阶段耗时。内核阶段把initcall_debug打开跑一次看看哪些驱动的初始化最耗时然后针对性地改成模块或者延迟加载。用户态阶段OpenBMC 的systemd服务里有很多After和Requires的依赖关系梳理一遍把能并行的并行起来。实测下来启动时间从 38 秒压到了 19 秒左右。其中 U-Boot 省了 2 秒内核省了 8 秒用户态省了 9 秒。用户态这块收益最大因为 OpenBMC 默认的服务依赖链太长了很多服务其实可以并行启动。提示压缩启动时间时一定要保留一个“安全启动”的 fallback 机制。我有一次把某个关键服务设成了并行启动结果它依赖的 D-Bus 还没起来导致整个 BMC 起不来只能重新烧录。后来我在 systemd 里加了Afterdbus.service的硬依赖问题才解决。4. 系统服务与运行时优化实战内核和设备树调完之后系统能跑得比较顺了但离“好用”还有距离。这一层主要是在用户态做文章重点是服务精简、内存管理和 IO 调度。4.1 OpenBMC 服务精简关掉那些“看起来有用”的服务OpenBMC 默认启用的服务里有不少是面向通用场景的比如phosphor-hwmon的某些实例、phosphor-sel-logger的冗余配置、以及一些调试用的服务。我的做法是先用systemctl list-units --typeservice把所有服务列出来然后逐个确认是否真的需要。关服务的时候要注意依赖关系。比如phosphor-ipmi-host依赖phosphor-ipmi-net你关掉后者前者也会起不来。建议用systemctl list-dependencies先看一眼依赖树再决定关哪些。我实际关掉的服务包括phosphor-debug-collector调试用产线不需要、phosphor-certificate-manager如果不用 HTTPS 客户端认证、以及obmc-console的某些实例。关完之后内存占用从 380MB 降到了 260MB 左右启动时间又少了 2 秒。4.2 内存与 IO 调度让数据流更顺畅RK3568 的内存带宽有限如果多个任务同时抢内存延迟就会上来。我的做法是给关键任务设置内存亲和性让它们尽量在同一个 NUMA 节点上跑虽然 RK3568 是单节点但可以通过numactl做内存绑定减少跨核访问。IO 调度方面OpenBMC 默认用的是cfq或者bfq这两个调度器在嵌入式场景下开销偏大。我一般改成mq-deadline或者none如果是 eMMC 或者 NVMe。实测下来日志写入的延迟从平均 12ms 降到了 4ms 左右。另外vm.dirty_ratio和vm.dirty_background_ratio这两个参数也值得调。默认值分别是 20 和 10在内存紧张的嵌入式设备上偏大。我一般设成 10 和 5这样脏页能更及时地刷回存储避免突然的大批量写入导致卡顿。4.3 中断亲和性与实时性调优如果你的 RK3568 上跑了 EtherCAT 主站或者摄像头采集这类实时性任务中断亲和性就很重要了。默认情况下所有中断都往 CPU0 上怼CPU0 很容易被压垮。我的做法是把网口、USB、摄像头这些外设的中断分散到 CPU1 到 CPU3 上CPU0 专门留给系统调度和实时任务。具体操作是改/proc/irq/irq_num/smp_affinity或者用irqbalance服务自动分配。不过irqbalance在嵌入式上有点重我一般直接写死亲和性。这里有个经验EtherCAT 主站的中断最好独占一个核心并且把这个核心的isolcpus设上避免被其他任务打扰。我在 RK3568 上试过把 CPU3 隔离出来专门跑 EtherCAT周期抖动能控制在 50 微秒以内基本满足工业场景的要求。5. 替代方案探索当原生方案顶不住时有些场景下无论怎么优化原生方案就是达不到要求。这时候就得考虑替代思路。这一层不是否定 OpenBMC而是在特定约束下找更合适的组合。5.1 轻量级 BMC 方案什么时候该考虑换OpenBMC 的优势是生态完整、功能全但代价是资源占用偏高。如果你的 RK3568 只需要做简单的带外管理比如风扇控制、温度监控、电源管理那完全可以考虑更轻量的方案。我试过用busybox加几个自写的守护进程来替代 OpenBMC 的核心功能内存占用能压到 50MB 以内启动时间 5 秒左右。代价是没有 IPMI、Redfish 这些标准接口需要自己实现。如果你的项目对标准化接口没要求这条路是可行的。另一个思路是用OpenBMC的裁剪版只保留phosphor-dbus-interfaces和phosphor-logging这两个核心组件其他全部自己写。这样既能复用 OpenBMC 的 D-Bus 模型又能控制资源占用。5.2 实时性任务的替代EtherCAT 主站的选型考量RK3568 上跑 EtherCAT 主站常见的选择有 IGH 和 Acontis。IGH 是开源的移植成本低但实时性依赖内核的PREEMPT_RT补丁。Acontis 是商业方案实时性更好但授权费用不低。我的建议是如果周期要求在 1ms 以上IGH 加PREEMPT_RT足够如果要求 250 微秒以下那得考虑 Acontis 或者换带 PRU 的平台。RK3568 本身没有 PRU纯靠 CPU 跑实时任务抖动会比较大。移植 IGH 的时候关键是把网卡驱动改成native模式并且把网卡中断绑定到隔离核心上。另外PREEMPT_RT补丁要和 RK3568 的内核版本匹配版本不对会编译失败。我用的 5.10 内核配PREEMPT_RT5.10-rt 补丁实测下来周期抖动在 80 微秒左右。5.3 摄像头接入的替代思路OV5695 与 OV8858 的取舍RK3568 的 MIPI CSI 接口可以接 OV5695 和 OV8858 这两款常见的摄像头。OV5695 是 500 万像素OV8858 是 800 万像素。如果只是做简单的图像采集OV5695 足够而且驱动更成熟资源占用更低。如果一定要上 OV8858要注意它的带宽需求更高会挤占内存带宽。我的做法是把摄像头的采集分辨率降到 1080p帧率降到 15fps这样对系统的影响就小很多。另外摄像头的v4l2缓冲区数量也要调默认的 4 个缓冲区在 RK3568 上容易导致丢帧我一般设成 6 到 8 个。5.4 国产化替代的边界哪些能替哪些不能现在国产化替代是个热词但替代不是目的解决问题才是。在 RK3568 加 OpenBMC 这个组合里能替代的部分主要是应用层的组件比如用国产的 Web 服务器替代 Nginx用国产的数据库替代 SQLite。但底层的 D-Bus、systemd 这些替代成本太高收益也不明显不建议动。我的原则是替代方案必须能解决一个具体问题而不是为了替代而替代。如果原生方案能通过优化达到要求那就优化如果优化到头了还是不行再考虑替代。这个顺序不能反。6. 常见问题与排查技巧实录这一节整理我在 RK3568 上跑 OpenBMC 时遇到的一些典型问题以及排查思路。这些问题不一定每个人都会碰到但碰到了能快速定位能省不少时间。6.1 启动卡死与 soft lockup 的排查路径启动卡死是最让人头疼的问题因为串口可能都没输出。我的排查顺序是先确认 U-Boot 能不能进命令行能进说明硬件没问题然后看内核有没有输出如果内核输出到某一行就停了基本可以确定是那个驱动的问题。soft lockup的排查稍微复杂一点。我一般先看dmesg里是哪个 CPU 报的然后看那个 CPU 上跑的是什么任务。如果是ksoftirqd那就是中断处理的问题需要检查中断亲和性和中断处理函数的耗时。如果是用户态任务那就用perf top看看是哪个函数在耗 CPU。有一次我遇到soft lockup查了半天发现是phosphor-hwmon在轮询一个不存在的传感器每次轮询都超时导致 CPU 被占满。后来在配置里把那个传感器去掉就好了。所以遇到这类问题先检查配置再怀疑代码。6.2 网络延迟与丢包的调优记录RK3568 的网口在 OpenBMC 下默认配置可能不是最优的。我遇到过 ping 延迟忽高忽低的情况排查下来是网卡的interrupt coalescing参数设得太激进导致中断合并过度延迟上来了。调整方法是ethtool -C eth0 rx-usecs 50 tx-usecs 50把中断合并的时间窗口调小。另外txqueuelen也可以适当调大默认是 1000我一般设成 2000减少丢包。如果是 EtherCAT 场景网卡最好用native驱动并且关掉NAPI用轮询模式这样延迟更稳定。6.3 触摸屏方向与显示异常的快速修复RK3568 接 MIPI 屏的时候触摸方向不对是常见问题。如果是竖屏改横屏需要在设备树里改touchscreen-swapped-x-y和touchscreen-inverted-x/y这几个属性。具体改哪个取决于你的屏是怎么装的。显示异常的话先检查panel节点的timing参数尤其是clock-frequency和hactive、vactive。这些参数不对屏幕会花屏或者不亮。我一般对照屏的规格书逐个核对别嫌麻烦这一步错了后面全白搭。6.4 常见问题速查表问题现象可能原因排查方法解决思路启动卡死无输出U-Boot 或内核配置错误串口抓 log确认卡在哪一步回退配置逐个排查soft lockup中断处理耗时过长看 dmesg 和 top调整中断亲和性优化驱动网络延迟高中断合并过度ethtool -C 查看参数调小 rx-usecs 和 tx-usecs触摸方向不对设备树属性配置错误检查 touchscreen 节点改 swapped-x-y 和 inverted 属性摄像头丢帧缓冲区不足v4l2-ctl 查看 buffer 数增加缓冲区数量内存占用高服务过多systemctl 列出服务关掉不必要的服务启动时间长服务依赖链太长systemd-analyze 分析并行化启动精简依赖7. 一些个人体会与后续可扩展的方向折腾 RK3568 上的 OpenBMC 这段时间我最大的感受是性能优化不是一次性的工作而是一个持续的过程。你今天调好的参数可能明天加了一个新功能就不适用了。所以与其追求一个“最优配置”不如建立一套“可观测、可回退”的机制。我现在的做法是每次改动都记录在案并且保留一个已知稳定的配置作为 fallback这样即使改出问题也能快速恢复。另外替代方案的选择要务实。OpenBMC 本身是个很优秀的项目大部分场景下通过优化都能满足要求。只有在确实遇到瓶颈并且替代方案能带来明确收益时才值得去折腾。我见过有人为了“轻量”把 OpenBMC 换成了自己写的裸机程序结果维护成本高得吓人这就本末倒置了。后续如果还要继续深挖我觉得这几个方向值得试试一是把 RK3568 的 NPU 利用起来做一些本地的异常检测减少对云端或主机的依赖二是研究一下PREEMPT_RT和 OpenBMC 的深度整合让实时任务和带外管理能更好地共存三是看看能不能把启动时间压到 10 秒以内这对某些需要快速响应的工业场景会很有价值。这些我还在摸索有进展了再分享。
返回列表