2007年2月13日 星期二

MPSAFE

The purpose of INTR_MPSAFE is to tell kernel subroutines that the owner will do the locking itself. Otherwise the kernel interrupt-scheduling routing will lock the kernel, or known as "Giant Lock", to prevent mis-behaviored interrupt handler, etc., from breaking the kernel.

First if INTR_MPSAFE is given, IH_MPSAFE is flagged in struct intr_handler. In intr_event_add_handler():

...
if (flags & INTR_MPSAFE)
ih->ih_flags |= IH_MPSAFE;
...


Then in ithread_execute_handlers():

...
if (!(ih->ih_flags & IH_MPSAFE))
mtx_lock(&Giant);
ih->ih_handler(ih->ih_argument);
if (!(ih->ih_flags & IH_MPSAFE))
mtx_unlock(&Giant);
...


So with debug.bootverbose=1, drivers that do not flag INTR_MPSAFE or INTR_FAST will show as GIANT-LOCKED:

...
atkbd0: [GIANT-LOCKED]
psm0: unable to allocate IRQ
psmcpnp0: <PS/2 mouse port> irq 12 on acpi0
psm0: current command byte:0047
psm0: <PS/2 Mouse> irq 12 on atkbdc0
ioapic0: routing intpin 12 (ISA IRQ 12) to vector 54
psm0: [GIANT-LOCKED]
psm0: model IntelliMouse, device ID 3-00, 3 buttons
psm0: config:00000000, flags:00000008, packet size:4
psm0: syncmask:08, syncbits:00
...


These are printed in bus_setup_intr():

...
if (!(flags & (INTR_MPSAFE | INTR_FAST)))
device_printf(dev, "[GIANT-LOCKED]\n");
if (bootverbose && (flags & INTR_MPSAFE))
device_printf(dev, "[MPSAFE]\n");
if (flags & INTR_FAST)
device_printf(dev, "[FAST]\n");
...

沒有留言:

張貼留言