__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 を初期化以降のコードを見るに
で、テンポラリな状態を本体に反映させた後に、action が NULL だったら (期待はされていない)、out にジャンプする、と。
上記コードを見るに、割り込みを受け付けたんですが、DISABLED なんだよねー、という状態もあり得るんだろな。こうした処置を見るに、ハードに近い低水準な層って面倒見るのが大変なんだろなー、と思う。