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 命令が抑制するのはハードウェア割り込みで、例外割り込みには有効ではないとの事。このあたりの切り分けを再確認した方が良いな。