nmi_watchdog功能测试及解析

本文介绍了NMI_Watchdog的功能和原理,涉及软lockup和硬lockup的检测机制。通过测试展示了如何触发softlockup和hardlockup,并分析了相关 Panic 日志,讨论了其在内核开发和用户态hang检测中的应用与局限性。
  • 由 b178903294创建, 最后修改于9月 23, 2019

 

严格意义来讲nmi_watchdog  ,属于中断检测范畴,是基于非屏蔽中断NMI的检测机制,是一种内核状态监护的狗,关于其介绍可参考nmi_watchdog.txt

1

2   [NMI watchdog is available for x86 and x86-64 architectures] 

3    

4   Is your system locking up unpredictably? No keyboard activity, just 

5   a frustrating complete hard lockup? Do you want to help us debugging 

6   such lockups? If all yes then this document is definitely for you. 

7    

8   On many x86/x86-64 type hardware there is a feature that enables 

9   us to generate 'watchdog NMI interrupts'.  (NMI: Non Maskable Interrupt 

10  which get executed even if the system is otherwise locked up hard). 

11  This can be used to debug hard kernel lockups.  By executing periodic 

12  NMI interrupts, the kernel can monitor whether any CPU has locked up, 

13  and print out debugging messages if so.

14 

15  In order to use the NMI watchdog, you need to have APIC support in your

16  kernel. For SMP kernels, APIC support gets compiled in automatically. For

17  UP, enable either CONFIG_X86_UP_APIC (Processor type and features -> Local

18  APIC support on uniprocessors) or CONFIG_X86_UP_IOAPIC (Processor type and

19  features -> IO-APIC support on uniprocessors) in your kernel config.

20  CONFIG_X86_UP_APIC is for uniprocessor machines without an IO-APIC.

21  CONFIG_X86_UP_IOAPIC is for uniprocessor with an IO-APIC. [Note: certain

22  kernel debugging options, such as Kernel Stack Meter or Kernel Tracer,

23  may implicitly disable the NMI watchdog.]

24 

25  For x86-64, the needed APIC is always compiled in.

26 

27  Using local APIC (nmi_watchdog=2) needs the first performance register, so

28  you can't use it for other purposes (such as high precision performance

29  profiling.) However, at least oprofile and the perfctr driver disable the

30  local APIC NMI watchdog automatically.

31 

32  To actually enable the NMI watchdog, use the 'nmi_watchdog=N' boot

33  parameter.  Eg. the relevant lilo.conf entry:

34 

35          append="nmi_watchdog=1"

36 

37  For SMP machines and UP machines with an IO-APIC use nmi_watchdog=1.

38  For UP machines without an IO-APIC use nmi_watchdog=2, this only works

39  for some processor types.  If in doubt, boot with nmi_watchdog=1 and

40  check the NMI count in /proc/interruptsif the count is zero then

41  reboot with nmi_watchdog=2 and check the NMI count.  If it is still

42  zero then log a problem, you probably have a processor that needs to be

43  added to the nmi code.

44 

45  A 'lockup' is the following scenario: if any CPU in the system does not

46  execute the period local timer interrupt for more than 5 seconds, then

47  the NMI handler generates an oops and kills the process. This

48  'controlled crash' (and the resulting kernel messages) can be used to

49  debug the lockup. Thus whenever the lockup happens, wait 5 seconds and

50  the oops will show up automatically. If the kernel produces no messages

51  then the system has crashed so hard (eg. hardware-wise) that either it

52  cannot even accept NMI interrupts, or the crash has made the kernel

53  unable to print messages.

54 

55  Be aware that when using local APIC, the frequency of NMI interrupts

56  it generates, depends on the system load. The local APIC NMI watchdog,

57  lacking a better source, uses the "cycles unhalted" event. As you may

58  guess it doesn't tick when the CPU is in the halted state (which happens

59  when the system is idle), but if your system locks up on anything but the

60  "hlt" processor instruction, the watchdog will trigger very soon as the

61  "cycles unhalted" event will happen every clock tick. If it locks up on

62  "hlt"then you are out of luck -- the event will not happen at all and the

63  watchdog won't trigger. This is a shortcoming of the local APIC watchdog

64  -- unfortunately there is no "clock ticks" event that would work all the

65  time. The I/O APIC watchdog is driven externally and has no such shortcoming.

66  But its NMI frequency is much higher, resulting in more significant hit

67  to the overall system performance.

68 

69  On x86 nmi_watchdog is disabled by default so you have to enable it with

70  a boot time parameter.

71 

72  It's possible to disable the NMI watchdog in run-time by writing "0" to

73  /proc/sys/kernel/nmi_watchdog. Writing "1" to the same file will re-enable

74  the NMI watchdog. Notice that you still need to use "nmi_watchdog=" parameter

75  at boot time.

76 

77  NOTE: In kernels prior to 2.4.2-ac18 the NMI-oopser is enabled unconditionally

78  on x86 SMP boxes.

 

 

简而言之就是NMI要基于APIC,还要考虑硬件平台的中断架构,由于我们seewobook SN21采用的是intel N3350所以中断架构就是SMP,所以我们的nmi_watchdog=1,也就是I/O APIC watchdog。其缺点很明显:每个时钟周期都要触发NMI,这对性能是个不小的影响,引用上面的原话           "...its NMI frequency is much higher, resulting in a more significant hit to the overall system performance",cpu性能大概消耗近1%,这对于一个监护程序来说很夸张了。而且可靠性不太好。

关于死锁检测原理可参照:https://blog.csdn.net/zhouhuacai/article/details/78046077

1.先来看看softlockup相关的原理和测试:

SoftLockup 检测首先需要对每一个CPU core注册叫做watchdog的kernel线程。即[watchdog/0],[watchdog/1],[watchdog/2]…

同时,系统会有一个高精度的计时器hrtimer(一般来源于APIC),该计时器能定期产生时钟中断,该中断对应的中断处理例程是kernel/watchdog.c: watchdog_timer_fn(),在该例程中:
- 要递增计数器hrtimer_interrupts,这个计数器同时为hard lockup detector用于判断CPU是否响应中断;
- 还要唤醒[watchdog/x]内核线程,该线程的任务是更新一个时间戳;
- soft lock detector检查时间戳,如果超过soft lockup threshold一直未更新,说明[watchdog/x]未得到运行机会,意味着CPU被霸占,也就是发生了soft lockup。

注意,这里面的内核线程[watchdog/x]的目的是更新时间戳,该时间戳是被watch的对象。而真正的看门狗,则是由时钟中断触发的 watchdog_timer_fn(),这里面 [watchdog/x]是被scheduler调用执行的,而watchdog_timer_fn()则是被中断触发的。
 

 

下面贴出nmi_watchdog 检测softlockup触发panic的主逻辑代码:

kernel/watchdog.c

static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)

  {

          unsigned long touch_ts = __this_cpu_read(watchdog_touch_ts);

          struct pt_regs *regs = get_irq_regs();

          int duration;

          int softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace;

 

          /* kick the hardlockup detector */

          watchdog_interrupt_count();

 

          /* test for hardlockups on the next cpu */

          watchdog_check_hardlockup_other_cpu();

 

          /* kick the softlockup detector */

          wake_up_process(__this_cpu_read(softlockup_watchdog));

 

          /* .. and repeat */

          hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period));

+         printk(KERN_INFO

+                       "now we test nmi_watchdog,touch_ts=%ld\n",touch_ts);

          if (touch_ts == 0) {     

                           if (unlikely(__this_cpu_read(softlockup_touch_sync))) {

                          /*  

                           * If the time stamp was touched atomically

                           * make sure the scheduler tick is up to date.

                           */

                          __this_cpu_write(softlockup_touch_sync, false);

                          sched_clock_tick();         

                          }

 

                  /* Clear the guest paused flag on watchdog reset */

                  kvm_check_and_clear_guest_paused();

                  __touch_watchdog();

                  return HRTIMER_RESTART;

          }

 

          /* check for a softlockup

           * This is done by making sure a high priority task is

           * being scheduled.  The task touches the watchdog to

           * indicate it is getting cpu time.  If it hasn't then

           * this is a good indication some task is hogging the cpu

           */

+       printk(KERN_INFO

+                      "that maybe occur softlockup,touch_ts=%ld  is_softlockup=%d\n",touch_ts,is_softlockup(touch_ts));

 

        duration = is_softlockup(touch_ts);

        if (unlikely(duration)) {

                /*

                 * If a virtual machine is stopped by the host it can look to

                 * the watchdog like a soft lockup, check to see if the host

                 * stopped the vm before we issue the warning

                 */

                if (kvm_check_and_clear_guest_paused())

                        return HRTIMER_RESTART;

 

                /* only warn once */

                if (__this_cpu_read(soft_watchdog_warn) == true) {

                        /*

                         * When multiple processes are causing softlockups the

                         * softlockup detector only warns on the first one

                         * because the code relies on a full quiet cycle to

                         * re-arm.  The second process prevents the quiet cycle

                         * and never gets reported.  Use task pointers to detect

                         * this.

                         */

                        if (__this_cpu_read(softlockup_task_ptr_saved) !=

                            current) {

                                __this_cpu_write(soft_watchdog_warn, false);

                                __touch_watchdog();

                        }

                        return HRTIMER_RESTART;

                }

 

                if (softlockup_all_cpu_backtrace) {

                        /* Prevent multiple soft-lockup reports if one cpu is already

                         * engaged in dumping cpu back traces

                         */

                        if (test_and_set_bit(0, &soft_lockup_nmi_warn)) {

                                /* Someone else will report us. Let's give up */

                                __this_cpu_write(soft_watchdog_warn, true);

                                return HRTIMER_RESTART;

                        }

                }

                pr_emerg("BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",

                        smp_processor_id(), duration,

                        current->comm, task_pid_nr(current));

                __this_cpu_write(softlockup_task_ptr_saved, current);

                print_modules();

                print_irqtrace_events(current);

                if (regs)

                        show_regs(regs);

                else

                        dump_stack();

 

                if (softlockup_all_cpu_backtrace) {

                        /* Avoid generating two back traces for current

                         * given that one is already made above

                         */

                        trigger_allbutself_cpu_backtrace();

 

                        clear_bit(0, &soft_lockup_nmi_warn);

                        /* Barrier to sync with other cpus */

                        smp_mb__after_atomic();

                }

 

                add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK);

                if (softlockup_panic)

                        panic("softlockup: hung tasks");

                __this_cpu_write(soft_watchdog_warn, true);

        else

                __this_cpu_write(soft_watchdog_warn, false);

 

        return HRTIMER_RESTART;

}

上述代码通过if (touch_ts == 0)  判断是否返回退出,没发生softlockup的时候,touch_ts全都为负或0,所以其int值均为0,总是返回退出,当touch_ts如同log里面大于0时,就要跳过if语句开始执行后面的代码了。通过这两句duration = is_softlockup(touch_ts); if (unlikely(duration))   来判断softlockup超时时间,大于零就开始执行panic流程。打印一条pr_emerg("BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n", smp_processor_id(), duration, current->comm, task_pid_nr(current));接着panic打印一条panic("softlockup: hung tasks");   这与下面我们测试看到的log信息一致,如果panic没有死的话我们的系统就会重启了,并保存相关log到/var/spool/crash/下,开机第一件事情就是把这个目录下的log全部保存,因为过一会儿系统会删除掉,这些log对于定位死锁内核程序很有帮助。

我们在kernel/kernel目录下编译个内核模块,启动系统后装载进内核来测试nmi_watchdog的功能。代码如下:

kernel/softlockup.c

#include<linux/kernel.h>

#include<linux/module.h>

#include<linux/kthread.h>

#include <linux/spinlock.h>

struct task_struct *task0;

static spinlock_t spinlock;

int val;

 

int task(void *arg)

{

    printk(KERN_INFO "%s:%d\n",__func__,__LINE__);

    /* To generate panic uncomment following */

    /* panic("softlockup: hung tasks"); */

 

    while(!kthread_should_stop()) {

        printk(KERN_INFO "%s:%d\n",__func__,__LINE__);

        spin_lock(&spinlock);

        /* busy loop in critical section */

        while(1) {

            printk(KERN_INFO "%s:%d\n",__func__,__LINE__);

        }

 

        spin_unlock(&spinlock);

    }

 

    return val;

}

 

static int softlockup_init(void)

{

    printk(KERN_INFO "%s:%d\n",__func__,__LINE__);

 

    val = 1;

    spin_lock_init(&spinlock);

    task0 = kthread_run(&task,(void *)(long)val,"softlockup_thread");

    set_cpus_allowed_ptr(task0, cpumask_of(0));

 

    return 0;

}

 

static void softlockup_exit(void)

{

    printk(KERN_INFO "%s:%d\n",__func__,__LINE__);

    kthread_stop(task0);

}

MODULE_LICENSE("GPL");

module_init(softlockup_init);

module_exit(softlockup_exit);

上述代码是从网上找到的,它通过spinlock()实现关抢占,使得该CPU上的[watchdog/x]无法被调度。另外,通过set_cpus_allowed_ptr()将该线程绑定到特定的CPU上去。

别忘了在kernel/Makefile文件中加入一行:obj-m +=softlockup.o          我们不直接装载到内核中,因为这样系统会有几率从开机开始一直重复触发softlockup,不是卡死就是循环重启,我们没办法看log。

编译完成后我们直接把新编译的kernel部署到seewobook上。开机后insmod  /lib/module/4.4.159/kernel/kernel/softlockup.ko   就开始测试了。

经过测试,发现进行softlockup后,nmi_watchdog有几率会重启,说明确实稳定行不行。nmi_watchdog成功检测softlockup并触发panic相关log如下:

 展开源码

2.hardlockup原理和测试

nmi_watchdog最主要的功能是检测hardlockup,这个才是他的主业。检测hard lockup的原理利用了PMU的NMI perf event,因为NMI中断是不可屏蔽的,在CPU不再响应中断的情况下仍然可以得到执行,它再去检查时钟中断的计数器hrtimer_interrupts是否在保持递增,如果停滞就意味着时钟中断未得到响应,也就是发生了hard lockup。
 

 

代码实现原理就是读取现在的hrtimer_interrupts和之前存储的数值进行比较,如果两个值一样,那么说明中断被阻塞了即发生了hardlockup,那么就要开始触发panic了。代码如下:

#ifdef CONFIG_HARDLOCKUP_DETECTOR_NMI

  /* watchdog detector functions */

  static bool is_hardlockup(void)

  {

          unsigned long hrint = __this_cpu_read(hrtimer_interrupts);

~         printk(KERN_INFO

+                         "now we test nmi_watchdog,hrtimer_intettupts_saved=%ld hrint=%ld\n",__this_cpu_read(hrtimer_interrupts_saved),hrint);

          if (__this_cpu_read(hrtimer_interrupts_saved) == hrint)

                  return true;

 

          __this_cpu_write(hrtimer_interrupts_saved, hrint);

          return false;

  }

  #endif

控制触发panic逻辑代码如下:

static void watchdog_overflow_callback(struct perf_event *event,

                   struct perf_sample_data *data,

                   struct pt_regs *regs)

  {

          /* Ensure the watchdog never gets throttled */

          event->hw.interrupts = 0;

 

          if (__this_cpu_read(watchdog_nmi_touch) == true) {

                  __this_cpu_write(watchdog_nmi_touch, false);

                  return;

          }

 

          /* check for a hardlockup

           * This is done by making sure our timer interrupt

           * is incrementing.  The timer interrupt should have

           * fired multiple times before we overflow'd.  If it hasn't

           * then this is a good indication the cpu is stuck

           */

          if (is_hardlockup()) {                                                          //通过这里进入panic流程

                  int this_cpu = smp_processor_id();

 

                  /* only print hardlockups once */

                  if (__this_cpu_read(hard_watchdog_warn) == true)

                          return;

 

                  pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu);            //输出log

                  print_modules();

                  print_irqtrace_events(current);

                  if (regs)

                          show_regs(regs);

                  else

                          dump_stack();

 

                  /*

                   * Perform all-CPU dump only once to avoid multiple hardlockups

                   * generating interleaving traces

                   */

                  if (sysctl_hardlockup_all_cpu_backtrace &&

                                  !test_and_set_bit(0, &hardlockup_allcpu_dumped))

                          trigger_allbutself_cpu_backtrace();

 

                  if (hardlockup_panic)

                          panic("Hard LOCKUP");                                           //触发panic

 

                  __this_cpu_write(hard_watchdog_warn, true);

                  return;

          }

 

          __this_cpu_write(hard_watchdog_warn, false);

          return;

  }

 

hardlockup测试代码:

hardlockup.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/kthread.h>

#include <linux/spinlock.h>

 

MODULE_LICENSE("GPL");

 

static int

hog_thread(void *data)

{

    static DEFINE_SPINLOCK(lock);

    unsigned long flags;

 

    printk(KERN_INFO "Hogging a CPU now\n");

    spin_lock_irqsave(&lock, flags);

    while (1);

 

    /* unreached */

    return 0;

}

 

static int __init

hog_init(void)

{

    kthread_run(&hog_thread, NULL, "hog");

    return 0;

}

MODULE_LICENSE("GPL");

module_init(hog_init);

在上述实例中,中断被关闭,普通中断无法被相应(包括时钟中断),线程无法被调度,因此,在这种情况下,不仅仅[watchdog/x]线程也无法工作,hrtimer也无法被相应。编译和安装操作参考上面softlockup测试。

 

触发hardlockup重启后的crash log如下:

 折叠源码

<6>[   59.148291] now we test nmi_watchdog,touch_ts=0

<6>[   60.624320] now we test nmi_watchdog,hrtimer_intettupts_saved=25 hrint=25                //hrint不再更新说明已经发生了hardlockup

<0>[   60.624324] NMI watchdog: Watchdog detected hard LOCKUP on cpu 0                         // 开始panic流程    pr_emerg 输出相应log

<4>[   60.624327] Modules linked in: hardlockup cmac rfcomm uinput snd_soc_sst_bxt_da7219_max98357a snd_soc_hdac_hdmi snd_soc_skl_ssp_clk snd_soc_dmic snd_soc_skl snd_soc_skl_ipc snd_soc_sst_ipc snd_soc_sst_dsp snd_soc_sst_match snd_hda_ext_core snd_hda_core acpi_als snd_soc_max98357a snd_soc_da7219 bridge stp llc zram ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_mark v4l2loopback fuse ip6table_filter iio_trig_sysfs cros_ec_sensors cros_ec_sensors_ring cros_ec_sensors_core industrialio_triggered_buffer kfifo_buf industrialio iwlmvm iwlwifi iwl7000_mac80211 cfg80211 btusb btrtl btbcm btintel uvcvideo videobuf2_vmalloc bluetooth videobuf2_memops videobuf2_v4l2 videobuf2_core joydev

<4>[   60.624402] CPU: 0 PID: 2363 Comm: hog Not tainted 4.4.159 #163

<4>[   60.624405] Hardware name: Google Coral/Coral, BIOS SN21.10176.68.2019_08_06_0950 03/02/2018

<4>[   60.624408] task: ffff88016506d580 task.stack: ffff88006a67c000

<4>[   60.624410] RIP: 0010:[<ffffffffc065a023>]  [<ffffffffc065a023>] hog_thread+0x23/0x1000 [hardlockup]

<4>[   60.624418] RSP: 0018:ffff88006a67fe98  EFLAGS: 00000082

<4>[   60.624420] RAX: 0000000000000282 RBX: ffff880175b7b840 RCX: 0000000000000001

<4>[   60.624422] RDX: ffff88017fc11a60 RSI: ffff88017fc0f1c0 RDI: ffffffffc065c000

<4>[   60.624425] RBP: ffff88006a67fe98 R08: 0000000000000021 R09: 0000000000000000

<4>[   60.624427] R10: 00000000066c0a10 R11: ffffffff93c86d7c R12: ffff88006a67fef0

<4>[   60.624429] R13: ffff88016506d580 R14: ffffffffc065a000 R15: 0000000000000000

<4>[   60.624432] FS:  0000000000000000(0000) GS:ffff88017fc00000(0000) knlGS:0000000000000000

<4>[   60.624434] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033

<4>[   60.624436] CR2: 000078acb25cb450 CR3: 000000006a43c000 CR4: 0000000000340670

<4>[   60.624438] Stack:

<4>[   60.624441]  ffff88006a67ff48 ffffffff93acf3a7 0000000000000000 ffffffff941fd570

<4>[   60.624447]  0000000000000000 ffffffff00000000 dead4ead00000000 00000000ffffffff

<4>[   60.624453]  ffffffffffffffff ffff88006a67fee0 ffff88006a67fee0 88fa469600000000

<4>[   60.624459] Call Trace:

<4>[   60.624469]  [<ffffffff93acf3a7>] kthread+0xb9/0xc9

<4>[   60.624474]  [<ffffffff941fd570>] ? __switch_to_asm+0x40/0x70

<4>[   60.624478]  [<ffffffff93acf2ee>] ? rcu_read_unlock_sched_notrace+0x48/0x48

<4>[   60.624481]  [<ffffffff941fd5ee>] ret_from_fork+0x4e/0x80

<4>[   60.624485]  [<ffffffff93acf2ee>] ? rcu_read_unlock_sched_notrace+0x48/0x48

<4>[   60.624487] Code: <eb> fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

<0>[   60.624522] Kernel panic - not syncing: Hard LOCKUP                                    //触发的panic

<4>[   60.624525] CPU: 0 PID: 2363 Comm: hog Not tainted 4.4.159 #163

<4>[   60.624527] Hardware name: Google Coral/Coral, BIOS SN21.10176.68.2019_08_06_0950 03/02/2018

<4>[   60.624529]  ffff88017fc09ef8 88fa469670f29fd2 ffff88017fc09a78 ffffffff93d2ade8

<4>[   60.624535]  ffff88017fc09ab0 ffffffff93d2ad9a 0000000000000000 0000003000000010

<4>[   60.624541]  0000000000000086 88fa469670f29fd2 ffffffff945e2d99 ffff88017fc09b38

<4>[   60.624547] Call Trace:

<4>[   60.624549]  <NMI>  [<ffffffff93d2ade8>] __dump_stack+0x19/0x1b

<4>[   60.624557]  [<ffffffff93d2ad9a>] dump_stack+0x4f/0x84

<4>[   60.624562]  [<ffffffff93ab6491>] panic+0xd1/0x221

<4>[   60.624567]  [<ffffffff93b2aedd>] watchdog_overflow_callback+0xf7/0x102

<4>[   60.624571]  [<ffffffff93b52426>] __perf_event_overflow+0x140/0x1ad

<4>[   60.624574]  [<ffffffff93b522e4>] perf_event_overflow+0x18/0x1a

<4>[   60.624579]  [<ffffffff93a65665>] intel_pmu_handle_irq+0x235/0x440

<4>[   60.624586]  [<ffffffff93a5f39b>] perf_event_nmi_handler+0x2c/0x49

<4>[   60.624589]  [<ffffffff93a4f554>] nmi_handle+0x72/0x160

<4>[   60.624593]  [<ffffffffc065a001>] ? hog_thread+0x1/0x1000 [hardlockup]

<4>[   60.624596]  [<ffffffff93a4f16f>] do_nmi+0x8b/0x36f

<4>[   60.624599]  [<ffffffffc065a000>] ? 0xffffffffc065a000

<4>[   60.624603]  [<ffffffff941ff4dd>] end_repeat_nmi+0x87/0x8f

<4>[   60.624606]  [<ffffffffc065a000>] ? 0xffffffffc065a000

<4>[   60.624611]  [<ffffffff93c86d7c>] ? ramoops_pstore_read+0x634/0x634

<4>[   60.624615]  [<ffffffffc065a023>] ? hog_thread+0x23/0x1000 [hardlockup]

<4>[   60.624618]  [<ffffffffc065a023>] ? hog_thread+0x23/0x1000 [hardlockup]

<4>[   60.624622]  [<ffffffffc065a023>] ? hog_thread+0x23/0x1000 [hardlockup]

<4>[   60.624624]  <<EOE>>  [<ffffffff93acf3a7>] kthread+0xb9/0xc9

<4>[   60.624629]  [<ffffffff941fd570>] ? __switch_to_asm+0x40/0x70

<4>[   60.624633]  [<ffffffff93acf2ee>] ? rcu_read_unlock_sched_notrace+0x48/0x48

<4>[   60.624637]  [<ffffffff941fd5ee>] ret_from_fork+0x4e/0x80

<4>[   60.624640]  [<ffffffff93acf2ee>] ? rcu_read_unlock_sched_notrace+0x48/0x48

<0>[   60.624720] Kernel Offset: 0x12a00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)

<0>[   60.626407] gsmi: Log Shutdown Reason 0x02

 

至此,nmi_watchdog相关的softlockup和hardlockup均已测试完毕,可见功能是正常的,只是稳定性可能差了一点。nmi_watchdog主要用于内核代码的检测和重置,主要在内核大神们开发阶段使用,一般是不建议在用户机中使用的,因为其不大稳定并且性能开销有点大,所以表现不大好。对于我们更常见的用户态hang的检测一般是交给softdog和iTCO_wdt的,softdog是完全基于软件的狗,所以也可能会随着系统崩溃而死掉,iTCO_wdt是基于硬件的 ,可靠性显然比前两个都高,但是由于SN21硬件配置错误导致iTCO_wdt已废,所以咱们目前只有指望这两个表现不大稳定的狗了,当这两个狗不起作用的时候还是老老实实F3+power手动重启吧。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值