ステータスの変更についてユーザーに通知を送信したいドライバーがあります。現在の実装では、proc ファイルシステムを使用してそうしています。読み取りプロセスread()
は、proc ファイルシステムにループします。カーネルが割り込みを受け取るまでのread()
ブロックは、関数を. これが基本的なコードです(不要な混乱をすべて取り除きました):wait_event_interruptible()
write_new_data()
call wake_up_interruptible()
static int flag=0;
DECLARE_WAIT_QUEUE_HEAD(info_wq);
//user process call read() on /proc/myfile to get to this function
int my_proc_read (struct file *filp, char *buf, size_t count, loff_t *pos)
{
wait_event_interruptible(info_wq, flag != 0);
flag = 0;
//copy buffers to user
return 0;
}
//when an interrupt comes it schedules this function on the systems' work queue
void write_new_data ()
{
//fill buffer with data
flag = 1;
wake_up_interruptible(&info_wq);
}
ここで、次の流れを考えてみましょう。
- ユーザー プロセスは を呼び出し
read()
、待機します。 - 割り込みが発生 ->
write_new_data()
が呼び出されます。データを書き込み、 を呼び出しますwake_up_interruptible()
。 read()
目覚め、データを読み取りますが、プロセスは読み取りを再実行していません (実行がスケジュールされておらず、次の割り込みのために取得できませんでした...)。- 割り込みが発生 ->
write_new_data()
再びトリガーされ、呼び出しますwake_up_interruptible()
が、待機中のスレッドは待機していません... - プロセス呼び出しの読み取りとブロック。
注: これはすべてユニプロセッサ システムで発生します。また、新しいデータを読み取るスレッドと書き込むスレッドは 1 つだけです。
2 番目の割り込みを見逃さないようにするにはどうすればよいですか? (1 つの解決策は netlink ソケットを使用することですが、/proc ランドでそれを行う方法があるかどうか疑問に思っていました)