NMI에 의한 커널 패닉 현상에 대하여

sohn9086의 이미지

커널 디버깅에 대해서 고수님들께 좀 여쭤보려고 합니다.

디버깅 환경
- CPU : Core 2 Duo E 6400
- Chipset : Q965 + ICH8DO
- Distribution : CentOS 5.4
- Kernel version : 2.6.30.10 (vanilla)

머신에서 특정 조작을 수행하면 커널 패닉이 일어나는 현상이 있어서 현재 디버깅중입니다.(재현율 100%는 아니고, 세번중 한번꼴로 발생합니다.)

디버깅을 위해 커널 crash dump를 떠 보았더니 아래와 같은 메세지를 보여주는군요.

crash 4.1.2-4.el5.centos
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009  Red Hat, Inc.
Copyright (C) 2004, 2005, 2006  IBM Corporation
Copyright (C) 1999-2006  Hewlett-Packard Co
Copyright (C) 2005, 2006  Fujitsu Limited
Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.
Copyright (C) 2005  NEC Corporation
Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions.  Enter "help copying" to see the conditions.
This program has absolutely no warranty.  Enter "help warranty" for details.
 
GNU gdb 6.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
 
      KERNEL: vmlinux
    DUMPFILE: vmcore
        CPUS: 2
        DATE: Mon Jul  5 17:36:16 2010
      UPTIME: 00:06:57
LOAD AVERAGE: 0.43, 1.36, 0.79
       TASKS: 270
    NODENAME: localhost.localdomain
     RELEASE: 2.6.30.10-debug
     VERSION: #1 SMP Fri Jun 18 17:01:36 JST 2010
     MACHINE: i686  (2128 Mhz)
      MEMORY: 2 GB
       PANIC: ""
         PID: 0
     COMMAND: "swapper"
        TASK: c07b3300  (1 of 2)  [THREAD_INFO: c080e000]
         CPU: 0
       STATE: TASK_RUNNING (ACTIVE)
     WARNING: panic task not found
 
crash> bt
PID: 0      TASK: c07b3300  CPU: 0   COMMAND: "swapper"
 #0 [c080eee0] crash_nmi_callback at c0410dcb
 #1 [c080eee4] notifier_call_chain at c06a02b1
 #2 [c080ef04] __atomic_notifier_call_chain at c06a02de
 #3 [c080ef14] atomic_notifier_call_chain at c06a02ec
 #4 [c080ef24] notify_die at c0441cb3
 #5 [c080ef40] do_nmi at c069e8f1
 #6 [c080ef64] nmi at c069e6a0
    EAX: 00000000  EBX: 00000000  ECX: 00000000  EDX: 00000000  EBP: c080efc0
    DS:  007b      ESI: 00000000  ES:  007b      EDI: c080bedc  GS:  0000
    CS:  0060      EIP: c0408c41  ERR: 00000000  EFLAGS: 00000246
 #7 [c080ef98] mwait_idle at c0408c41
 #8 [c080efc4] cpu_idle at c0401ce7

대충 보아하니 CPU idle중에 NMI가 발생해서 죽어버린 듯한 것 같아, 처음에는 watchdog을 의심했습니다.
그러나, BIOS의 watchdog옵션은 disable로 되어있기 때문에 아마 아닌 것 같습니다.
그래도 혹시나 해서 조금 구글링을 해보니 APIC에서 특정 주기로 발생시키는 NMI를 이용하는 nmi watchdog이라는 게 있다고 하네요. 그런데 그 기능이 제대로 동작하려면 /proc/interrupts에서 NMI로 표시되는 인터럽트가 발생해야 한다는데 제 환경에서는 발생하지 않는걸로 보아 역시 그것도 아닌 것 같습니다.

할 수 없이 소스를 따라 가 보았습니다. do_nmi함수안에서 불리워지는 default_do_nmi를 보니 아래와 같이 되어있더군요.

static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
{
    unsigned char reason = 0;
    int cpu;
 
    cpu = smp_processor_id();
 
    /* Only the BSP gets external NMIs from the system. */
    if (!cpu)
        reason = get_nmi_reason();
 
    if (!(reason & 0xc0)) {
        if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
                                == NOTIFY_STOP)
            return;
#ifdef CONFIG_X86_LOCAL_APIC
        /*
         * Ok, so this is none of the documented NMI sources,
         * so it must be the NMI watchdog.
         */
        if (nmi_watchdog_tick(regs, reason))
            return;
        if (!do_nmi_callback(regs, cpu))
            unknown_nmi_error(reason, regs);
#else
        unknown_nmi_error(reason, regs);
#endif
 
        return;
    }
    if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
        return;
 
    /* AK: following checks seem to be broken on modern chipsets. FIXME */
    if (reason & 0x80)
        mem_parity_error(reason, regs);
    if (reason & 0x40)
        io_check_error(reason, regs);
#ifdef CONFIG_X86_32
    /*
     * Reassert NMI in case it became active meanwhile
     * as it's edge-triggered:
     */
    reassert_nmi();
#endif
}

crash의 백트레이스 결과로 보아

        if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
                                == NOTIFY_STOP)

아마도 이 부분이 불리워진게 아닌가 하는데, 혹시 이런 이유로 커널이 죽을 때, 그것이 무엇을 뜻하는 것인지 경험해 보신 분이 계신가요?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.