__do_IRQ() について (その2)

続きです。はてなは半角6万5千文字まで許容との事なので、そんなに心配せずエントリ入れようとしてるんですが、大丈夫かなぁ。ま、いいや。(余談

IRQ_PER_CPU なブロックの次には、準備てきな手続きが列挙されている、って感じ。コードの引用ってコメントを抜くべきなんだろうか、駄目なんだろうか、と思いつつもコメント削除分を以下に。
__do_IRQ()#kernel/irq/handle.c

    spin_lock(&desc->lock);
    desc->handler->ack(irq);

    status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
    status |= IRQ_PENDING;

    action = NULL;
    if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
        action = desc->action;
        status &= ~IRQ_PENDING;
        status |= IRQ_INPROGRESS;
    }
    desc->status = status;

    if (unlikely(!action))
        goto out;

まず、spin_lock して ACK を PIC 方面に送信。
その後、IRQ ディスクリプタの状態 (status) を設定。

  • IRQ_REPLAY フラグの解除
    REPLAY な状態はIRQ ラインは禁止されているが、以前発生した IRQ に対する応答 (ACK) をまだ PIC に返していない状態 (詳解 Linux カーネルより引用)との事なのでフラグの解除はある意味ビンゴ (本当?
  • IRQ_WAITINGフラグの解除
    WITING な状態はハードウェアデバイス検出処理のため、カーネルが IRQ ラインを使用しており、対象のデバイスが割り込みを発生させる前の状態 (詳解 Linux カーネルより引用)との事よりこちらもビンゴ

その後、状態に IRQ_PENDING を追加。(って言い方は微妙?)

それ以降の一連の手続きは、ホンマに handle_IRQ_event() 呼ぶかどうか、というか主に IRQ_INPROGRESS な状態かどうか (競合?) によってそれ以降の手続きを続行するかどうかを判断している、と言える。

likely/unlikely について補足
基本的にはマクロの引数が条件文となる。コンパイル後に

  • likely の場合は then ブロックが近いアドレスに配置される
  • unlikely の場合は else ブロック (無い場合はナニ) が近いアドレスに配置される

なコードを吐く。ので、コードを読むだけなら無視。(こら

それを踏まえて action を初期化以降のコードを見るに

  • IRQ の状態が IRQ_DISABLED か IRQ_INPROGRESS でない場合には
    • action に IRQ ディスクリプタの action の値を設定
    • status を IRQ_PENDING ではない状態に。
      IRQ_PENDING はライン上に IRQ が発生しており、応答 (ACK) は PIC に返されているが、カーネルがまだ割り込みハンドラを実行していない状態。(詳解 Linux カーネルより引用)という事で今から正に割り込みハンドラを実行する訳です。
    • で、statusを IRQ_INPROGRESS な状態に。
      IRQ_INPROGRESS は引用するまでもなく、割り込みハンドラ実行中、な状態だろな、と。

で、テンポラリな状態を本体に反映させた後に、action が NULL だったら (期待はされていない)、out にジャンプする、と。

上記コードを見るに、割り込みを受け付けたんですが、DISABLED なんだよねー、という状態もあり得るんだろな。こうした処置を見るに、ハードに近い低水準な層って面倒見るのが大変なんだろなー、と思う。