【原創】linux實時作業系統xenomai看門狗(watchdog)機制及作用介紹

沐多發表於2024-11-26

版權宣告:本文為本文為博主原創文章,轉載請註明出處 https://www.cnblogs.com/wsg1100。如有錯誤,歡迎指正。

目錄
  • 一、前言
    • PREEMPT-RT(RT Throttling)
  • 一、xenomai watchdog介紹
  • 二、xenomai watchdog工作原理
  • 三、使用場景

本文介紹xenomai watchdog,有什麼用?它是如何工作的?

一、前言

介紹xenomai watchdog之前,有必要先介紹作業系統對實時任務的排程,實時任務的排程是指在滿足實時任務時間約束的情況下,對任務進行排隊和執行的策略。兩種常見的實時任務排程演算法是RR排程(Round Robin,輪轉排程)和FIFO排程(First In First Out,先進先出排程)。

正常情況下,高優先順序實時任務對CPU時間絕對的優先權。如果此時最高優先順序任務存在bug,出錯或進入一個不存在主動和被動讓出CPU資源的邏輯時,系統中的滑鼠、鍵盤、螢幕等非實時任務將會因為得不到CPU執行時間餓死,導致系統失去響應。

為此PREEMPT-RT和xenomai給出了不同的解決方案。

PREEMPT-RT(RT Throttling)

對於PREEMPT-RT,PREEMPT-RT提供了一個機制,確保非實時任務能在某個時間點執行,該機制也被稱為RT限流(RT Throttling),它由兩個值決定:

  • /proc/sys/kernel/sched_rt_period_us 定義了微秒級別的視窗,在這個視窗裡排程器會在實時和非實時任務之間共享資源,預設1 s。

  • /proc/sys/kernel/sched_rt_runtime_us 則規定了在上述視窗中為實時任務分配的時長比例。預設值950000us,即95%。意味著實時任務在每 1 秒內最多可以使用 950 毫秒的 CPU 時間,剩餘的 50 毫秒留給其他非實時任務。

可以透過以下方式修改這些值:

echo 950000 > /proc/sys/kernel/sched_rt_runtime_us
echo 1000000 > /proc/sys/kernel/sched_rt_period_us

需要注意的是,修改這些值需要超級使用者(root)許可權。

RT Throttling保證了即使實時任務出現錯誤或者無限迴圈,也會為非實時任務預留一定的CPU執行時間,方便我們定位和debug。

xenomai也有實時任務的限制措施xenomai watchdog,但與PREEMPT-RT的RT Throttling不同。

一、xenomai watchdog介紹

xenomai watchdog是xenomai核心提供的一個檢測xenomai實時任務是否長期佔用CPU機制,核心編譯時透過以下配置啟用該功能。

[*] Xenomai/cobalt  ---> 
     [*]   Debug support  --->
    		[*]   Watchdog support
    		(4)     Watchdog timeout 

其中Watchdog timeout是看門狗動作的超時時間,時間單位是秒,允許配置的預設最大時間為60秒。核心啟用後,看門狗超時時間還可透過核心引數watchdog_timeout在啟動時修改,單位:秒,值不受限制。

當xenomai watchdog觸發時,watchdog會向當前cpu執行的執行緒傳送SIGDEBUG signal,該訊號會使實時任務結束,同時核心會輸出資訊,實時任務結束後系統恢復響應,透過demsg命令可以看到。

[Xenomai] watchdog triggered on CPU #0 -- runaway thread 'RT_Thread' signaled

那xenomai watchdog是如何工作的?有什麼侷限?不使用會發生什麼?

二、xenomai watchdog工作原理

我們知道Xenomai 是一個雙排程核作業系統,它在核心態新增了一個高優先順序的實時排程核 Cobalt 來管理實時任務。Cobalt 排程核與 Linux 排程核共存,透過 Ipipeline 機制將兩個排程上下文分為實時域和非實時域,Ipipeline 確保了 Cobalt 核心(實時域)的優先順序高於 Linux 核心(非實時域,也稱root domain),linux核心退化為成為 Cobalt 核心的idle任務,從而保障實時任務的實時性;(有關該部分,請查閱本部落格其他文章)。

實時域和非實時域會隨著任務的執行情況而來回切換。當沒有實時任務需要執行釋放CPU資源給linux非實時任務,或者實時任務呼叫了linux提供的系統資源的實時,會切換到非實時域。

看門狗的觸發邏輯是這樣的,當進入實時任務排程上下文的時候,看門狗啟動開始定時,離開實時上下文(實時任務呼叫了非實時服務或者主動睡眠讓出 cpu) 停止,只要看門狗超時說明實時任務在這段時間內一直在執行,看門狗看管的是整個實時任務集合,不是某個特定任務,看門狗超時觸發的時候會把當前 cpu 執行的任務 kill 掉,任何一個實時任務都有可能在watchdog觸發這個時間點上

具體程式碼如下:

static inline void enter_root(struct xnthread *root)
{
	struct xnarchtcb *rootcb __maybe_unused = xnthread_archtcb(root);

#ifdef CONFIG_XENO_OPT_WATCHDOG
	xntimer_stop(&root->sched->wdtimer);
#endif
	/*...*/
}

static inline void leave_root(struct xnthread *root)
{
	struct xnarchtcb *rootcb = xnthread_archtcb(root);
	struct task_struct *p = current;

	/*...*/

#ifdef CONFIG_XENO_OPT_WATCHDOG
	xntimer_start(&root->sched->wdtimer, get_watchdog_timeout(),
		      XN_INFINITE, XN_RELATIVE);
#endif
}

而看門狗處理邏輯也很簡單,如果當前處於是root域,不處理;若當前是使用者態實時任務,則直接傳送訊號;若當前執行的核心態實時任務,則將當前任務狀態設定為XNKICKED並取消執行。

static void watchdog_handler(struct xntimer *timer)
{
	struct xnsched *sched = xnsched_current();
	struct xnthread *curr = sched->curr;

	if (likely(xnthread_test_state(curr, XNROOT))) {/*當前處於root域*/
		xnsched_reset_watchdog(sched);
		return;
	}

	if (likely(++sched->wdcount < wd_timeout_arg))
		return;

	trace_cobalt_watchdog_signal(curr);

	if (xnthread_test_state(curr, XNUSER)) {	/*使用者態實時任務*/
		printk(XENO_WARNING "watchdog triggered on CPU #%d -- runaway thread "
		       "'%s' signaled\n", xnsched_cpu(sched), curr->name);
		xnthread_call_mayday(curr, SIGDEBUG_WATCHDOG);
	} else {								/*核心態實時任務*/
		printk(XENO_WARNING "watchdog triggered on CPU #%d -- runaway thread "
		       "'%s' canceled\n", xnsched_cpu(sched), curr->name);
		/*
		 * On behalf on an IRQ handler, xnthread_cancel()
		 * would go half way cancelling the preempted
		 * thread. Therefore we manually raise XNKICKED to
		 * cause the next call to xnthread_suspend() to return
		 * early in XNBREAK condition, and XNCANCELD so that
		 * @thread exits next time it invokes
		 * xnthread_test_cancel().
		 */
		xnthread_set_info(curr, XNKICKED|XNCANCELD);
	}

	xnsched_reset_watchdog(sched);
}

三、使用場景

xenomai watchdog會導致出問題的實時任務退出,所以一般在實時軟體開發階段,開啟watchdog可以儘早暴露實時應用潛在的出錯或無限迴圈問題,避免軟體釋出後產生嚴重後果。

如果實時應用釋出後,在特定場景下出現系統無響應問題,可用啟用watchdog來排查定位。

下一篇文章,我將給大家介紹一個真實生產環境中遇到的問題,一個外部條件觸發低優先順序實時任務進入無限迴圈邏輯後,導致整個系統實時任務排程異常的問題,敬請期待。

相關文章