环境:
RK3568芯片,Linux-5.10主线系统,buildroot-2021根文件系统
背景:
应用层有四个RT线程,十几个非实时线程,但是偶发最高优先级的RT线程执行超时情况,简短的无锁函数操作却执行了几十毫秒(极其不合理),该RT线程是1s内执行一次,每次0.0*ms耗时。
1. 分析RT线程:
htop排序后查看RT线程优先级,发现内核态RT线程优先级均小于应用层的RT线程,不会发生抢占情况

确认RT线程对所有CPU核心都具有亲和性,且调度策略均是SCHED_RR(时间片轮转,时间片为90ms)

同时确认CPU核心周期(1s)内可运行RT线程的时间为950ms,且下调该值到200ms,该问题必现,所以初步确认是CPU核心可运行RT线程的时间片用光,导致该RT线程未得到调度。
echo 200000 | tee /proc/sys/kernel/sched_rt_runtime_us
2. 解决问题
2.1 升级内核为RT内核
对Linux打RT补丁,选择的是PREEMPT_RT
patch -p1 < ../PREEMPT_RT/kernel-5.10/5.10.198/0001-patch-5.10.180-rt89.patch-on-rockchip-base-cae91899b.patch
patch -p1 < ../PREEMPT_RT/kernel-5.10/5.10.198/0002-patch-5.10.180-rt89.patch-fix-runtime-error-on-rockc.patch
patch -p1 < ../PREEMPT_RT/kernel-5.10/5.10.198/0003-arm64-configs-optimize-latency-for-PREEMPT_RT.patch
make ARCH=arm64 rockchip_linux_defconfig rockchip_rt.config
make ARCH=arm64 rk3568-evb1-ddr4-v10-linux.img -j16
打上RT补丁后,用cyclictest测试实时效果确实好了很多。PREEMPT_RT补丁是重写自旋锁、将所有硬件中断改写为可被抢占的RT线程等等。
但是运行应用层实测后仍然会有超时现象…
2.2 分析应用层代码
利用perf生成火焰图,确认能否优化应用层的RT线程代码;同时利用trace抓取内核事件,分析内核调度情况。

基于上方火焰图发现该优先级第二的RT线程中open和read系统调用很高,导致该线程运行耗时很多。排查后发现是该线程需要10ms更新一次16个gpio的状态,不停的open-read-close,后改为缓存fd的方式,耗时少了很多,见下图。

通过trace抓取内核事件,其中update_info每次被调度事件从0.4ms变成了0.176ms。

3. 总结
优化应用层代码后,暂时未出现超时现象。遇到此类实时性能问题,要么升级为RT内核,要么通过perf和trace优化应用层。
1703

被折叠的 条评论
为什么被折叠?



