2

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 を使用しています。

4

1 に答える 1