diff options
author | jhb <jhb@FreeBSD.org> | 2001-11-15 17:29:36 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-11-15 17:29:36 +0000 |
commit | e189eb8c72b1b31f4adb945631c5ab910d63931f (patch) | |
tree | 9faad756ef4ec37d9c9c9c619951443b69b6ba70 /sys | |
parent | 369c63dd8d807688c3054131dbb0252341f14302 (diff) | |
download | FreeBSD-src-e189eb8c72b1b31f4adb945631c5ab910d63931f.zip FreeBSD-src-e189eb8c72b1b31f4adb945631c5ab910d63931f.tar.gz |
- Don't enable interrupts in trap() if we trapped while holding a spin
lock as this usually makes the problem worse.
- If we get a page fault while holding a spin lock, treat it as a fatal
trap and don't even bother calling into the VM since calling into the
VM will panic when trying to lock Giant before we can get a useful
message anyways.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/trap.c | 23 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 23 |
2 files changed, 34 insertions, 12 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 714f3f2..23ad3fc 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -190,8 +190,7 @@ trap(frame) * interrupts and then trapped. Enabling interrupts * now is wrong, but it is better than running with * interrupts disabled until they are accidentally - * enabled later. XXX This is really bad if we trap - * while holding a spin lock. + * enabled later. */ type = frame.tf_trapno; if (ISPL(frame.tf_cs) == SEL_UPL || (frame.tf_eflags & PSL_VM)) @@ -206,10 +205,12 @@ trap(frame) printf("kernel trap %d with interrupts disabled\n", type); /* - * We should walk p_heldmtx here and see if any are - * spin mutexes, and not do this if so. + * Page faults need interrupts diasabled until later, + * and we shouldn't enable interrupts while holding a + * spin lock. */ - enable_intr(); + if (type != T_PAGEFLT && PCPU_GET(spinlocks) == NULL) + enable_intr(); } } @@ -223,9 +224,19 @@ trap(frame) * an interrupt gate for the pagefault handler. We * are finally ready to read %cr2 and then must * reenable interrupts. + * + * If we get a page fault while holding a spin lock, then + * it is most likely a fatal kernel page fault. The kernel + * is already going to panic trying to get a sleep lock to + * do the VM lookup, so just consider it a fatal trap so the + * kernel can print out a useful trap message and even get + * to the debugger. */ eva = rcr2(); - enable_intr(); + if (PCPU_GET(spinlocks) == NULL) + enable_intr(); + else + trap_fatal(&frame, eva); } if ((ISPL(frame.tf_cs) == SEL_UPL) || diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 714f3f2..23ad3fc 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -190,8 +190,7 @@ trap(frame) * interrupts and then trapped. Enabling interrupts * now is wrong, but it is better than running with * interrupts disabled until they are accidentally - * enabled later. XXX This is really bad if we trap - * while holding a spin lock. + * enabled later. */ type = frame.tf_trapno; if (ISPL(frame.tf_cs) == SEL_UPL || (frame.tf_eflags & PSL_VM)) @@ -206,10 +205,12 @@ trap(frame) printf("kernel trap %d with interrupts disabled\n", type); /* - * We should walk p_heldmtx here and see if any are - * spin mutexes, and not do this if so. + * Page faults need interrupts diasabled until later, + * and we shouldn't enable interrupts while holding a + * spin lock. */ - enable_intr(); + if (type != T_PAGEFLT && PCPU_GET(spinlocks) == NULL) + enable_intr(); } } @@ -223,9 +224,19 @@ trap(frame) * an interrupt gate for the pagefault handler. We * are finally ready to read %cr2 and then must * reenable interrupts. + * + * If we get a page fault while holding a spin lock, then + * it is most likely a fatal kernel page fault. The kernel + * is already going to panic trying to get a sleep lock to + * do the VM lookup, so just consider it a fatal trap so the + * kernel can print out a useful trap message and even get + * to the debugger. */ eva = rcr2(); - enable_intr(); + if (PCPU_GET(spinlocks) == NULL) + enable_intr(); + else + trap_fatal(&frame, eva); } if ((ISPL(frame.tf_cs) == SEL_UPL) || |