1. 程式人生 > >報錯kernel:NMI watchdog: BUG: soft lockup - CPU#0 stuck for 26s

報錯kernel:NMI watchdog: BUG: soft lockup - CPU#0 stuck for 26s

堆棧 超時 函數 roo aid 時鐘中斷 機制 int return

近期在服務器跑大量高負載程序,造成cpu soft lockup。如果確認不是軟件的問題。

解決辦法:

#追加到配置文件中

echo 30 > /proc/sys/kernel/watchdog_thresh

#查看

[root@git-node1 data]# tail -1 /proc/sys/kernel/watchdog_thresh
30

#臨時生效

sysctl -w kernel.watchdog_thresh=30

#內核軟死鎖(soft lockup)bug原因分析

Soft lockup名稱解釋:所謂,soft lockup就是說,這個bug沒有讓系統徹底死機,但是若幹個進程(或者kernel thread)被鎖死在了某個狀態(一般在內核區域),很多情況下這個是由於內核鎖的使用的問題。


vi /etc/sysctl.conf

kernel.watchdog_thresh=30

參考文章:

CentOS內核,對應的文件是/proc/sys/kernel/watchdog_thresh。
CentOS內核和標準內核還有一個地方不一樣,就是處理CPU占用時間過長的函數,CentOS下是watchdog_timer_fn()函數。
如果你的內核是標準內核的話,可以通過修改/proc/sys/kernel/softlockup_thresh來修改超時的閾值
參考文獻:https://zhidao.baidu.com/question/1829924822713415300.html

首先,這條信息可以輸出,說明即使發生死鎖或者死循環,還是有代碼可以執行。第二,可以通過這個日誌信息,找到對應的處理函數,這個函數所在的模塊就是用來處理CPU被過度使用時用到的。所以通過這個事情,可以看到內核打印出的只言片語都有可能成為你解決問題的關鍵,一定要從重視這些信息,從中找出有用的東西。
我經常看的內核版本是官方的2.6.32內核,這個版本中我找到的函數是softlockup_tick(),這個函數在時鐘中斷的處理函數run_local_timers()中調用。這個函數會首先檢查watchdog線程是否被掛起,如果不是watchdog線程,會檢查當前占有CPU的線程占有的時間是否超過系統配置的閾值,即softlockup_thresh。如果當前占有CPU的時間過長,則會在系統日誌中輸出我們上面看到的那條日誌。接下來才是最關鍵的,就是輸出模塊信息、寄存器信息和堆棧信息,檢查softlockup_panic的值是否為1。如果softlockup_panic為1,則調用panic()讓內核掛起,輸出OOPS信息。代碼如下所示:/** This callback runs from the timer interrupt, and checks
* whether the watchdog thread has hung or not:*/void softlockup_tick(void){int this_cpu = smp_processor_id();
unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
unsigned long print_timestamp;
struct pt_regs *regs = get_irq_regs();
unsigned long now;
/* Warn about unreasonable delays: */
if (now <= (touch_timestamp + softlockup_thresh))return;
per_cpu(print_timestamp, this_cpu) = touch_timestamp;
spin_lock(&print_lock);
printk(KERN_ERR BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n,
this_cpu, now - touch_timestamp,
current-comm, task_pid_nr(current));
print_modules();
print_irqtrace_events(current);if (regs)show_regs(regs);elsedump_stack();
spin_unlock(&print_lock);
if (softlockup_panic)
panic(softlockup: hung tasks);}
但是softlockup_panic的值默認竟然是0,所以在出現死鎖或者死循環的時候,會一直只輸出日誌信息,而不會宕機,這個真是好坑啊!所以你得手動修改/proc/sys/kernel/softlockup_panic的值,讓內核可以在死鎖或者死循環的時候可以宕機。如果你的機器中安裝了kdump,在重啟之後,你會得到一份內核的core文件,這時從core文件中查找問題就方便很多了,而且再也不用手動重啟機器了。如果你的內核是標準內核的話,可以通過修改/proc/sys/kernel/softlockup_thresh來修改超時的閾值,如果是CentOS內核的話,對應的文件是/proc/sys/kernel/watchdog_thresh。CentOS內核和標準內核還有一個地方不一樣,就是處理CPU占用時間過長的函數,CentOS下是watchdog_timer_fn()函數。
這裏介紹下lockup的概念。lockup分為soft lockup和hard lockup。 soft lockup是指內核中有BUG導致在內核模式下一直循環的時間超過10s(根據實現和配置有所不同),而其他進程得不到運行的機會。hard softlockup是指內核已經掛起,可以通過watchdog這樣的機制來獲取詳細信息。

報錯kernel:NMI watchdog: BUG: soft lockup - CPU#0 stuck for 26s