一. 背景介绍:
softlock_up:
内核开关, 打开之后可以检测软锁。软锁发生之后, 当cpu在设定的时间间隔中没有发生时间中断的话, 该机制就会发送一个nmi中断, 让系统重启。该机制用看门狗机制实现。
nohz_full:
内核开关, 用于消除某个cpu上的时钟中断, 可以在uboot的cmdline里指定想要关闭时钟中断的cpu核心序号。该功能主要应用于一些对时间性能很敏感的系统, 因为任务切换会伴随着时钟中断, 其中的上下文切换会对任务的性能和实时性产生影响, 若应用需要强性能和强实时性, 最好的情况是一个任务独占一个cpu, 不做任何时间片切换。
一般该内核开关会伴随着核隔离使用, 下面是一个例子:
setenv bootargs '... isolcpus=5-7 nohz_full=5-7 rw'
arch_timer:
系统时钟
二. 问题描述
在一个需求中, dpdk需要在nohz_full和核隔离的情况使用。但是发现在4.19内核上打开了softlock_up和nohz_full隔离5~7号cpu。然而发现当两个内核开关打开的时候, 5 ~ 7号cpu依旧有来自于arch_timer的系统时钟。
使用cat /proc/interrupts | grep arch_timer
命令可以发现该中断在cpu 5 ~ 7 上增加。
但是根据内核文档[3], 发现该现象是和该模块设计思路相悖的, 于是开始调查。
默认情况下所有在线cpu上都会运行一个watchdog线程。不过在内核配置了”NO_HZ_FULL“的
情况下watchdog线程默认只会运行在管家(housekeeping)cpu上,而”nohz_full“启动参数指
定的cpu上则不会有watchdog线程运行。试想,如果我们允许watchdog线程在”nohz_full“指
定的cpu上运行,这些cpu上必须得运行时钟定时器来激发watchdog线程调度;这样一来就会
使”nohz_full“保护用户程序免受内核干扰的功能失效。当然,副作用就是”nohz_full“指定
的cpu即使在内核产生了lockup问题我们也无法检测到。不过,至少我们可以允许watchdog
线程在管家(non-tickless)核上继续运行以便我们能继续正常的监测这些cpus上的lockups
事件。
三. 调查
首先调查softlock_up相关代码, 发现具体实现在 kernel/watchdog.c
里, 其中开启softlock_up的watchdog入口函数为static void watchdog_enable(unsigned int cpu)
, 在同一个c文件里搜索其调用, 发现两处调用,
以下是整理的两条调用链,
①:
kernel_init
kernel_init_freeable
lockup_detector_init watchdog.c
lockup_detector_setup
lockup_detector_reconfigure
softlockup_start_all
softlockup_start_fn
watch