__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;
	}

amazon:Linux カーネル解析入門によると

	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 は見ておく事に。