死鎖就是多個進程(線程)因為等待別的進程已占有的自己所需要的資源而陷入阻塞的一種狀態(tài),死鎖狀態(tài)一旦形成,進程本身是解決不了的,需要外在的推動,才能解決,最重要的是死鎖不僅僅影響進程業(yè)務,而且還會占用系統(tǒng)資源,影響其他進程。所以內核中設計了內核死鎖檢測機制,一旦發(fā)現(xiàn)死鎖進程,就重啟OS,快刀斬亂麻解決問題。之所以使用重啟招數(shù),還是在于分布式系統(tǒng)中可以容忍單點崩潰,不能容忍單點進程計算異常,否則進行死鎖檢測重啟OS就得不償失了。 內核提供自旋鎖、信號量等鎖形式的工具,具體不再贅述。 Linux內核死鎖主要分為分為兩種:D狀態(tài)死鎖和R狀態(tài)死鎖。 一、D狀態(tài)死鎖檢測 D狀態(tài)死鎖:進程長時間處于TASK_UNINTERRUPTIBLE而不恢復的狀態(tài)。進程處于TASK_UNINTERRUPTIBLE狀態(tài),不響應其他信號(kill -9),保證一些內核原子操作不被意外中斷。但這種狀態(tài)時間長就表示進程異常了,需要處理。 內核D狀態(tài)死鎖檢測就是hung_task機制,主要代碼就在kernel/hung_task.c文件。 具體實現(xiàn)原理: 1.創(chuàng)建Normal級別的khungtaskd內核線程,在死循環(huán)中每隔sysctl_hung_task_timeout_secs時間后check一下,用schedule_timeout定時(節(jié)約定時器浪費的CPU)。 2.調用do_each_thread,while_each_thread宏遍歷所有的進程信息,如果有D狀態(tài)進程,則檢查最近切換次數(shù)和task計算是否一致,即最近是否有調度切換,如果一致,則沒有切換,打印相關信息,并根據(jù)sysctl_hung_task_panic開關決定是否重啟。 對應用戶態(tài)控制的proc接口有: /proc/sys/kernel/hung_task_timeout_secs,hung_task_panic等。 二、R狀態(tài)死鎖檢測 R狀態(tài)死鎖:進程長時間處于TASK_RUNNING 狀態(tài)搶占CPU而不發(fā)生切換,一般是,進程關搶占后一直執(zhí)行任務,或者進程關搶占后處于死循環(huán)或者睡眠,此時往往會導致多個CPU互鎖,整個系統(tǒng)異常。 補充:lockdep不是所謂的死鎖。 內核R狀態(tài)死鎖檢測機制就是lockdep機制,入口即是lockup_detector_init函數(shù)。 1.通過cpu_callback函數(shù)調用watchdog_enable,在每個CPU core上創(chuàng)建SCHED_FIFO級別的實時線程watchdog,其中使用了hrtimer定時器,控制檢查周期。 2.hrtimer定時器調用watchdog_timer_fn進行清狗的時間檢查,而線程則每次重置清狗時間,如果watchdog_timer_fn發(fā)現(xiàn)狗的重置時間已經和當前時間差出危險值,則根據(jù)開關進行panic處理。 對應用戶態(tài)控制的proc接口有: /proc/sys/kernel/watchdog_thresh,softlockup_panic等。 整個死鎖檢測機制比較簡單,但cpu_callback函數(shù)結構性設計巧妙,可以在很多地方參考使用。
|
|