Lions' 本読み (141)

らふてーを製造しつつ、rkintr を読む大晦日。
ええと、rkintr 手続きが続きの rkstart 手続きを呼び出しているので

  • rkstart 手続きで I/O キューから取り出して要求
  • devstart でレジスタに書き込み
  • rkintr で後処理をして rkstart 呼び出し

という一連の処理は同期的である、という理解で良いのかな。これを前提 (?) に中身を確認してみます。とりあえず以下な部分は保険なのかどうか。

5455    if (rktab.d_active == 0)
5456            return;

で、ここからが本番なのかどうか。とりあえず I/O キューの先頭を取り出してます。

5457    bp = rktab.d_actf;

基本的には rkstart 手続き関連で処理対象になったもの、という前提か。別途割り込み関連については確認しておく必要あり。rkintr なディスク割り込みはどの程度の優先度を持って実行されるのか、とか。
で、次の行で rktab.d_active が 0 で初期化されてエラー処理な記述があります。昨日エントリの引用 (テキスト 383p な記述) にあるステイタス情報が使われています。

5458    rktab.d_active = 0;
5459    if (RKADDR->rkcs < 0) { /* エラービット */
5460            deverror(bp, RKADDR->rker, RKADDR->rkds);

あわわ、ここの記述も凄いスね。

5461            RKADDR->rkcs = RESET|GO;
5462            while((RKADDR->rkcs&CTLRDY) == 0) ;

テキストによれば_数マイクロ秒_て。そしてリトライしたりしてますね。

5463            if (++rktab.d_errcnt <= 10) {
5464                    rkstart();
5465                    return;
5466            }

10 回リトライしてそれでも駄目な場合、諦めています。ここのリトライがあるから I/O キューはこの後に再設定、ということなのか。

5467            bp->b_flags =| B_ERROR;

で、以降がある意味正常系なんですね。

5469    rktab.d_errcnt = 0;
5470    rktab.d_actf = bp->av_forw;
5471    iodone(bp);
5472    rkstart();

d_errcnt 属性を 0 にして d_actf を更新しています。I/O キューは

  • d_actf が先頭
  • リンクは av_forw 属性のみを使っている
  • 最後尾は d_actl に格納

という規則があるみたいなんですが、d_actl てどこで使ってるのだろうか。

iodone 手続き

基本的には引数で渡される struct buf なオブジェクトについて名前の通り、_I/O が終わった_状態に、というのがテキスト 385p に記述されてます。

宿題

  • rkintr な割り込みハンドラの優先度確認
    • 割り込みハンドラ自体の優先度も確認
  • d_actl の使途

色々ヤりながら 17 以降も読む方向ですがどうなるやら。