2

ステータスの変更についてユーザーに通知を送信したいドライバーがあります。現在の実装では、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);
}  

ここで、次の流れを考えてみましょう。

  1. ユーザー プロセスは を呼び出しread()、待機します。
  2. 割り込みが発生 ->write_new_data()が呼び出されます。データを書き込み、 を呼び出しますwake_up_interruptible()
  3. read()目覚め、データを読み取りますが、プロセスは読み取りを再実行していません (実行がスケジュールされておらず、次の割り込みのために取得できませんでした...)。
  4. 割り込みが発生 ->write_new_data()再びトリガーされ、呼び出しますwake_up_interruptible()が、待機中のスレッドは待機していません...
  5. プロセス呼び出しの読み取りとブロック。

注: これはすべてユニプロセッサ システムで発生します。また、新しいデータを読み取るスレッドと書き込むスレッドは 1 つだけです。

2 番目の割り込みを見逃さないようにするにはどうすればよいですか? (1 つの解決策は netlink ソケットを使用することですが、/proc ランドでそれを行う方法があるかどうか疑問に思っていました)

4

2 に答える 2

4

ダン、これがwait_event_interruptibleのコードです:

#define wait_event_interruptible(wq, condition)             \
({                                  \
    int __ret = 0;                          \
    if (!(condition))                       \
        __wait_event_interruptible(wq, condition, __ret);   \
    __ret;                              \
})

「if(!(condition))」と「__ wait_event_interruptible」の間に割り込みが発生した場合、スリープが発生し、別の割り込みが発生するまで読み取りプロセスがブロックされます。

于 2012-11-26T11:10:59.487 に答える
3

wait_event_interruptibleとの呼び出しの間に割り込みが発生する可能性があるため、変数に望ましくないflag = 0影響を与える可能性があります。flag

UPマシンでも、構成によってはカーネルがプリエンプティブになる可能性があり、その結果、そのコードが影響を受けることに注意してください。

また、単純な「int」フラグを使用しないことをお勧めします。代わりに、atomic_tatomic_dec/inc_*操作を使用する必要があります。カーネル内での補完の実装を参照してください。これは、ここで行っているのと同様のことを行います。

質問自体について:

コードをwait_event_interruptible見ると、条件が真の場合はスリープが発生しないことがわかります。したがって、問題は問題ではありません。

于 2012-06-13T11:04:03.347 に答える