內核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的工作流程來介紹,而是着重對一些參數進行了分析以便後續工作中引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章