看門狗深度解析

        往往我們發現的HWT看門狗問題:都是CPU間共享資源互鎖造成的(即R 狀態死鎖),所以後續當發現HWT問題時,不要只是關注具體直接導致HWT對應的那個CPU核的堆棧信息,我們必須要查看每一個CPU堆棧信息。---------------其實往往此種問題是由於其它cpu核訪問資源異常時死在了鎖裏,而等待獲取資源的cpu核(直接報問題的核)由於長時間不能等到鎖被釋放造成被看門狗復位。

死鎖概念

死鎖是指多個進程(線程)因爲長久等待已被其他進程佔有的的資源而陷入阻塞的一種狀態。當等待的資源一直得不到釋放,死鎖會一直持續下去。死鎖一旦發生,程序本身是解決不了的,只能依靠外部力量使得程序恢復運行,例如重啓,開門狗復位等。

Linux 提供了檢測死鎖的機制,主要分爲 D 狀態死鎖和 R 狀態死鎖。

  • D 狀態死鎖    進程等待 I/O 資源無法得到滿足,長時間(系統默認配置 120 秒)處於 TASK_UNINTERRUPTIBLE 睡眠狀態,這種狀態下進程不響應異步信號(包括 kill -9)。如:進程與外設硬件的交互(如 read),通常使用這種狀態來保證進程與設備的交互過程不被打斷,否則設備可能處於不可控的狀態。對於這種死鎖的檢測 Linux 提供的是 hung task 機制,MTK 也提供 hang detect 機制來檢測 Android 系統 hang 機問題。觸發該問題成因比較複雜多樣,可能因爲 synchronized_irq、mutex lock、內存不足等。D 狀態死鎖只是局部多進程間互鎖,一般來說只是 hang 機、凍屏,機器某些功能沒法使用,但不會導致沒餵狗,而被狗咬死。
  • R 狀態死鎖  進程長時間(系統默認配置 60 秒)處於 TASK_RUNNING 狀態壟斷 CPU 而不發生切換,一般情況下是進程關搶佔或關中斷後長時候執行任務、死循環,此時往往會導致多 CPU 間互鎖,整個系統無法正常調度,導致餵狗線程無法執行,無法餵狗而最終看門狗復位的重啓。該問題多爲原子操作,spinlock 等 CPU 間併發操作處理不當造成。本文所介紹的 Lockdep 死鎖檢測工具檢測的死鎖類型就是 R 狀態死鎖。

常見錯誤

  • AA: 重複上鎖
  • ABBA: 曾經使用 AB 順序上鎖,又使用 BA 上鎖
  • ABBCCA: 這種類型是 ABBA 的擴展。AB 順序 , AB 順序,CA 順序。這種鎖人工很難發現。
  • 多次 unlock

下面舉一個ABBA死鎖類型的例子:

假設有兩處代碼(比如不同線程的兩個函數 thread_P 和 thread_Q)都要獲取兩個鎖(分別爲 lockA 和 lockB),如果 thread_P 持有 lockA 後再去獲取 lockB,而此時恰好由 thread_Q 持有 lockB 且它也正在嘗試獲取 lockA,那麼此時就是處於死鎖的狀態,這是一個最簡單的死鎖例子,也即所謂的 AB-BA 死鎖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
thread_P()
{
    ......
    spin_lock(&lockA);
    spin_lock(&lockB);
 
    spin_unlock(&lockA);
    spin_unlock(&lockB);
    ......
}
 
thread_Q()
{
    ......
    spin_lock(&lockB);
    spin_lock(&lockA);
 
    spin_unlock(&lockB);
    spin_unlock(&lockA);
    ......
}
當線程Q使用B鎖的時候其實是解不了鎖的,因爲線程P就沒有把B鎖釋放掉。-------切記:一定要注意順序。



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