linux-0.01 の hd.c なソレ
ええと、rw_abs_hd() 手続き末端のナニ。
add_request(req); wait_on_buffer(bh);
リクエストを enqueue して待っている模様。wait_on_buffer() の定義が以下。
static inline void wait_on_buffer(struct buffer_head * bh) { cli(); while (bh->b_lock) sleep_on(&bh->b_wait); sti(); }
b_lock 属性が 0 でない間、sleep_on し続ける。割り込みは無視。あと、sleep_on の中身もスルーしておきます。ここで問題にしたいのは struct buffer_head 型の b_lock 属性です。
b_lock 属性
この属性は lock_buffer() 手続きで 1 が代入されて unlock_buffer で 0 が代入されます。
static inline void lock_buffer(struct buffer_head * bh) { if (bh->b_lock) printk("hd.c: buffer multiply locked\n"); bh->b_lock=1; } static inline void unlock_buffer(struct buffer_head * bh) { if (!bh->b_lock) printk("hd.c: free buffer being unlocked\n"); bh->b_lock=0; wake_up(&bh->b_wait); }
シーケンスとしては
- rw_abs_hd() 手続きにて lock_buffer() 手続きが呼ばれて b_lock 属性が lock された状態 (1) となる
- add_request() 手続きでリクエストがキューイングされる
- wait_on_buffer() で待ち状態となる (ビジーループ)
- キューイングされたナニが取り出されて hd_interrput より {read, write}_intr() 手続きが呼び出される
- この中で unlock_buffer() 手続きが呼び出されて b_lock 属性が unlock された状態 (0) となる
- wait_on_buffer() 手続きから脱出
という事なのかな。本当にこれで良いのか、と思うんですがなんとなく整合してるカンジはします。
あら?
割り込み禁止でビジーループしてたら復帰できないあたり、整合性を欠いてる気がし始めた 0 時前な今日この頃orz
むむ
cli 命令が抑制するのはハードウェア割り込みで、例外割り込みには有効ではないとの事。このあたりの切り分けを再確認した方が良いな。