__do_IRQ() について
よっつくらいのブロックに分けてみる。まず最初。
__do_IRQ()#kernel/irq/handle.c
kstat_this_cpu.irqs[irq]++; if (desc->status & IRQ_PER_CPU) { irqreturn_t action_ret; /* * No locking required for CPU-local interrupts: */ desc->handler->ack(irq); action_ret = handle_IRQ_event(irq, regs, desc->action); desc->handler->end(irq); return 1; }
kstat_this_cpu.irqs[irq]++;
は
カウントアップしているのは、「割り込みの回数」を表わしています。「/proc/interrupts」で見える回数になります。(amazon:Linux カーネル解析入門より引用)
とある。探しかけたんですが、kstat_this_cpu (たしかマクロ) については別途。
で、次の条件分岐は irq_desc[irq].status の値を判定している。状態として IRQ_PER_CPU であれば
- 割り込みコントローラに ACK を返す (irq_desc[irq].handler->ack() の呼出し)
- 割り込みをマスク (同上)
- handle_IRQ_event() 呼出し
- 割り込みマスクの解除 (irq_desc[irq].handler->end() の呼出し)
の処理を行ない早々に関数から戻る記述となっている。
昨日のエントリで書いた通り、IRQ_PER_CPU は
Interrupt has been assingned to a particular CPU. Only used in SMP environments.
<超意訳>
割込みは特定の CPU にアサインされている。SMP 環境でのみ使用。超意訳>
たしかに spin_lock とかしてないし、IRQ の状態にもお構いなしな記述。
SMP もちょっと置いといた方が良さげ、ってコトでとりあえず、上記 ack() と end() にデフォルトで設定される mask_and_ack_8259A()#arch/i386/kernel/i8259.c と end_8259A_irq()#arch/i386/kernel/i8259.c は見ておく事に。