【問題排查】implicit declaration of function ‘interruptible_sleep_on‘處理
阿新 • • 發佈:2021-01-28
技術標籤:系統報錯及處理Linux 日常使用與開發linux問題排查git核心嵌入式
當前核心版本:3.18.y
原始碼對應的核心版本:2.6.37
問題
移植程式碼的時候報錯:
341:3: error: implicit declaration of function 'interruptible_sleep_on' [-Werror=implicit-function-declaration]
interruptible_sleep_on (&tty->read_wait);
^
一樣是比較兩個版本的核心原始碼,發現interruptible_sleep_on這個函式在新的核心中已經被去掉了。
單純的百度搜索不到任何有用的資訊...還有沒有什麼辦法?
思路
這裡提供一個辦法,可以嘗試在官方的核心原始碼的git提交日誌中,搜尋一些有用的資訊。
Ps:這裡前提肯定是用git下載linux核心原始碼了,需要對git有一定的熟悉度。
附上linux原始碼官網:https://www.kernel.org/
分析
通過"git log --grep=interruptible_sleep_on"命令,找到git提交日誌,並查到相關資訊:
commit 76ae0536ddc0aa576f2aac11f0f82d0fd60b522c
Author: Arnd Bergmann < [email protected]>
Date: Wed Feb 26 12:01:49 2014 +0100
parport: fix interruptible_sleep_on race
The interruptible_sleep_on function is can still lead to the
deadlock mentioned in the comment above the caller, and we want
to remove it soon, so replace it now with the race-free
wait_event_interruptible.
Signed-off-by: Arnd Bergmann < [email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
根據提交日誌上的內容,明白了原因是interruptible_sleep_on函式仍然會導致死鎖,因此被刪除了,解決辦法是立即使用無競爭的wait_event_interruptible替換它。
對應的替換函式:
【include/linux/wait.h】
#define __wait_event_interruptible(wq, condition) \
___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \
schedule())
/**
* wait_event_interruptible - sleep until a condition gets true
* @wq: the waitqueue to wait on
* @condition: a C expression for the event to wait for
*
* The process is put to sleep (TASK_INTERRUPTIBLE) until the
* @condition evaluates to true or a signal is received.
* The @condition is checked each time the waitqueue @wq is woken up.
*
* wake_up() has to be called after changing any variable that could
* change the result of the wait condition.
*
* The function will return -ERESTARTSYS if it was interrupted by a
* signal and 0 if @condition evaluated to true.
*/
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__ret = __wait_event_interruptible(wq, condition); \
__ret; \
})
再看看interruptible_sleep_on函式的定義,做一個比較:
void __sched interruptible_sleep_on(wait_queue_head_t *q)
{
sleep_on_common(q, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
}
Ps:新的wait_event_interruptible函式多了一個引數...就需要我們實際替換的時候,注意更多地方。
例項
講下我實際的程式碼中是如何替換的。
私有結構體中新增成員,對應condition。
bool write_done;
wait_queue_head_t write_wait;
在wake_up_interruptible函式之前設定write_done:
&trans->write_done = true;
wake_up_interruptible (&trans->write_wait);
在原先的interruptible_sleep_on函式處,替換為wait_event_interruptible:
trans->write_done = false;
wait_event_interruptible(&trans->write_wait, trans->write_done);
搞定~