内核softlockup和hardlockup的一些参数分析【转】

转自:https://www.cnblogs.com/liuhailong0112/p/17619657.html

一 参数配置

    Softlockup和hardlockup作为内核中的"lockup-看门狗"可以检查系统中调度和中断是否正常运转,其原理可以参考lockup-watchdogs。这两种watchdogs在/proc/sys/kernel/目录下有一些配置参数来对功能进行控制和调整

procfs下的接口文件名称 接口说明 内核中对应的变量 默认值 内核依赖配置 
watchdog

是否使能lockup watchdog,

是lockup检测的总开关

watchdog_user_enabled

1;

内核启动参数控制:

  nowatchdog,0

CONFIG_LOCKUP_DETECTOR
soft_watchdog

是否使能softlockup检测

soft_watchdog_user_enabled

1;

内核启动参数控制:

  nosoftlockup, 0

  

 CONFIG_LOCKUP_DETECTOR
nmi_watchdog

是否使能hardlockup检测

nmi_watchdog_user_enabled

NMI_WATCHDOG_DEFAULT

(CONFIG_HARDLOCKUP_DETECTOR

|CONFIG_HAVE_NMI_WATCHDOG

使能情况下值为1,否则为0);

 

内核启动参数控制:

  nmi_watchdog=0或者

  nmi_watchdog=1

CONFIG_LOCKUP_DETECTOR
watchdog_cpumask 标记哪些cpu上线lockup watchdog  watchdog_cpumask  housekeeping_cpumask(HK_FLAG_TIMER);  CONFIG_LOCKUP_DETECTOR
watchdog_thresh

lockup检测的阈值的基础参数;

softlockup和hardlockup的阈值通过

这个参数计算得到。

watchdog_thresh

10

内核启动参数控制:  

  watchdog_thresh=xx

CONFIG_LOCKUP_DETECTOR
softlockup_panic

发生softlockup事件时是否触发

系统panic

softlockup_panic CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE CONFIG_SOFTLOCKUP_DETECTOR
softlockup_all_cpu_backtrace 发生softlockup事件时是否打印各个

CPU的backtrace

sysctl_softlockup_all_cpu_backtrace 0

CONFIG_SOFTLOCKUP_DETECTOR

&&  CONFIG_SMP

hardlockup_panic  发生hardlockup事件时是否触发

系统panic

hardlockup_panic

CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE;

内核参数控制:

  nmi_watchdog=panic或者

  nmi_watchdog=nopanic控制

CONFIG_HARDLOCKUP_DETECTOR
hardlockup_all_cpu_backtrace 发生hardlockup事件时是否打印各个

CPU的backtrace

sysctl_hardlockup_all_cpu_backtrace 0

CONFIG_HARDLOCKUP_DETECTOR

&& CONFIG_SMP

 二 检查周期

    Lockup-watchdog是周期性采样来实施检查的。softlockup和hardlockup的采样源不一样,采样的周期也不一样,下面咱们来看看采样周期。

采样\名称 softlockup hardlockup
采样方式 hrtimer PMU CYCLES 
采样周期

sample_period = watchdog_thresh*2/5 (秒)

wd_attr->sample_period = watchdog_thresh(秒)

参数说明 watchdog_thresh默认为10

watchdog_thresh默认为10

2.1 softlockup检查周期

    Softlockup的检查周期保存在一个全局变量sample_period中,这个变量在lockup-watchdog初始化时调用lockup_detector_reconfigure()函数时计算得到:

复制代码
static int get_softlockup_thresh(void)
{
        return watchdog_thresh * 2;
}

static void set_sample_period(void)
{
        /*
         * convert watchdog_thresh from seconds to ns
         * the divide by 5 is to give hrtimer several chances (two
         * or three with the current relation between the soft
         * and hard thresholds) to increment before the
         * hardlockup detector generates a warning
         */
        sample_period = get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5);
}
复制代码

    通过这部分计算代码可以看到sample_period=watchdog_thresh*2/5。

2.2 hardlockup检查周期

    Hardlockup检查周期是在PMU event创建时候确定

复制代码
static int hardlockup_detector_event_create(void)
{
        struct perf_event_attr *wd_attr;
        //......    
        wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
       //......
}

u64 hw_nmi_get_sample_period(int watchdog_thresh)
{
        return (u64)(cpu_khz) * 1000 * watchdog_thresh;
}      
复制代码

    从这里看到hardlockup的perf event采样周期为 cpu_khz*1000 * watchdog_thresh。其中: cpu_khz是 CPU主频/1000,CPU主频即每秒cycle数。因此PMU cycles按此频率采样,就是watchdog_thresh秒。

三 门限

    首先以表格方式来看看softlockup和hardlockup两种lockup-watchdog的门限:

lockup\相关说明 门限计算式 默认值 相关参数
softlockup watchdog_thresh*2 20秒 watchdog_thresh,与sysctl kernel.watchdog_thresh关联
hardlockup watchdog_thresh * 4/5 8秒 watchdog_thresh,与sysctl kernel.watchdog_thresh关联

3.1 softlockup门限

    Softlockup门限是watchdog_thresh*2,其中watchdog_thresh可以通过/proc/sys/kernel/watchdog_thresh来配置。

static int get_softlockup_thresh(void)
{
        return watchdog_thresh * 2;
}

    所以softlockup门限默认值是20秒。

3.2 hardlockup门限

    Hardlockup的门限是watchdog_thresh * 4/5,默认情况下面hardlockup门限值就是8秒。

复制代码
static int get_softlockup_thresh(void)
{
        return watchdog_thresh * 2;  //watchdog来自于/proc/sys/kernel/watchdog_thresh
}

static void set_sample_period(void)
{      
        sample_period = get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5);
        watchdog_update_hrtimer_threshold(sample_period);
}


void watchdog_update_hrtimer_threshold(u64 period)
{
        watchdog_hrtimer_sample_threshold = period * 2;
}
复制代码

 四 保活周期

    下面是softlockup和hardlockup"保活"周期的一个分析。

lockup\说明 watchdog形式 周期 更新变量
softlockup stop worker sample_period percpu(watchdog_touch_ts)
hardlockup hrtimer sample_period percpu(hrtimer_interrupts)

4.1 softlockup保活

    Softlockup是以Linux中优先级最高的调度类中stop worker来进行保活;这个stop worker线程以sample_period为周期被hrtimer触发,sample_period也就是2.1中的softlockup检查周期:

stop_one_cpu_nowait(smp_processor_id(),
                                 softlockup_fn, NULL,
                                 this_cpu_ptr(&softlockup_stop_work))

    这个stop worker被触发后会去更新 watchdog_touch_ts这个每CPU变量:__this_cpu_write(watchdog_touch_ts, get_timestamp())

4.2 hardlockup保活 

    Hardlockup会有一个sample_period为周期的hrtimer反复触发去更新hrtimer_interrupts这个每CPU变量: __this_cpu_inc(hrtimer_interrupts)

hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period))

    此外,这个hrtimer也就是4.1中触发stop worker的hrtimer,没错,他们是复用的。 

总结

    本文以linux-5.10代码为背景进行分析。分析线条不是按照lockup-watchdog的工作流程来介绍,而是着重对一些参数进行了分析以便后续工作中引用。

posted @ 2023-11-02 17:41  Sky&Zhang  阅读(124)  评论(0编辑  收藏  举报