netlink ソケットを使用してカーネル モジュールと通信するマルチスレッド アプリケーションがあります。ユーザー モード アプリケーションのスレッドの 1 つがサーバーとして機能し、カーネル モジュールがクライアントとして機能します。大まかにカーネルコードは次のとおりです。
timeout = 3500;
netlink_unicast();
wait:
__set_current_state(TASK_INTERRUPTIBLE);
timeout = schedule_timeout(timeout);
__set_current_state(TASK_RUNNING);
if (!timeout)
{
printk(KERN_ERR "No response received\n");
return -1;
}
if (message_status != UPDATED)
{
printk(KERN_ERR "Somebody woke us up before we got a reply. Time left %d\n", timeout);
__set_current_state(TASK_INTERRUPTIBLE);
goto wait;
}
ユーザーモードアプリケーションがこのメッセージに応答すると、netlink コールバックで message_status 変数が更新されます。したがって、基本的には、メッセージを送信してから、最大タイムアウト jiffies で応答を待つという考え方です。
ここで、gdb を使用して、ユーザー モードで netlink サーバー スレッドによって呼び出される任意の関数にブレーク ポイントを追加すると、ブレーク ポイントにヒットすることはなく、カーネル ログに次のようなメッセージが殺到します。
返事が来る前に誰かが私たちを起こしてしまいました。残り時間 3499
返事が来る前に誰かが私たちを起こしてしまいました。残り時間 3499
返事が来る前に誰かが私たちを起こしてしまいました。残り時間 3499
返事が来る前に誰かが私たちを起こしてしまいました。残り時間 3499
..
..
返事が来る前に誰かが私たちを起こしてしまいました。残り時間 3498
やっと手に入るまで
応答がありません
カーネル スレッドがタイムアウトから復帰する原因と、ユーザー モード コードをデバッグする方法を教えてください。
PS: RHEL 6.0 で 2.6.32-71.el6.x86_64 を使用しています。