ドライバーがすぐに要求に応じられない場合の対応を検討する必要があります。通常、呼び出しプロセスはドライバーのステータスを気にしないため、ドライバー内でそれに応じて処理する必要があります。一般的なアプローチは、プロセスへのリクエストをブロックすることです。
I/O のブロックとは、デバイス操作の実行時に必要なリソースを取得できない場合、操作が実行される前に操作可能な条件が満たされるまで現在のプロセスが一時停止されることを意味します。一時停止されたプロセスはスリープ状態になり、待機条件が満たされるまでスケジューラの実行キューから削除されます。逆に、ノンブロッキング I/O では、デバイス操作が実行できない場合でもプロセスは一時停止されませんが、操作を実行できるようになるまでポーリングを中止するか続行することが選択されます。
#1. ドライバーでの I/O 処理フローのブロック#「」
待機キューは、ブロッキング I/O を処理するための古典的なメカニズムです。
」
#RK3399 の ISP ドライバーでは、データ構造
struct rkisp1_stream に
wait_queue_head_tned; が含まれています。
init_waitqueue_head(&stream->done); を呼び出して初期化操作を実行します。
リーリー
wait_queue_head_t
__wait_queue_head です。
リーリー
init_waitqueue_head()
実際に実行される関数は
で、その関数定義は次のとおりです。
void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *key) { spin_lock_init(&q->lock); lockdep_set_class_and_name(&q->lock, key, name); INIT_LIST_HEAD(&q->task_list); }
调用DECLARE_WAITQUEUE(wait, current)
将当前进程初始化为等待队列。注意,这里的等待队列和等待队列链表头可不是一个东东。
#define DECLARE_WAITQUEUE(name, tsk) \ wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
等待队列的定义如下:
struct __wait_queue { unsigned int flags; void *private; wait_queue_func_t func; struct list_head task_list; };
等待队列和等待队列链表头是通过add_wait_queue()
结合到一起的。
init_waitqueue_head(&delay_wait); add_wait_queue(&delay_wait, &wait);
以上代码是将等待队列进程加入到等待队列链表中:
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) { list_add(&new->task_list, &head->task_list); }
阻塞进程处理包括两部分内容,首先设置进程的睡眠状态,包括TASK_INTERRUPTIBLE
和TASK_UNINTERRUPTIBLE
两种。前者用于可中断睡眠,后者用于不可中断睡眠。然后,将当前进程退出调度器让出CPU的使用权。
set_current_state(TASK_INTERRUPTIBLE); schedule();
唤醒处理通常位于中断处理函数或某些动作成功执行之后,特定条件满足时,唤醒通过阻塞队列睡眠的进程。例如:
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int success, int behind) { if (!bitmap) return; if (behind) { if (atomic_dec_and_test(&bitmap->behind_writes)) wake_up(&bitmap->behind_wait); pr_debug("dec write-behind count %d/%lu\n", atomic_read(&bitmap->behind_writes), bitmap->mddev->bitmap_info.max_write_behind); } ... }
以上がLinux ドライバーで IO プロセスをブロックするための処理メカニズムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。