- 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.
This commit is contained in:
John Baldwin 2001-11-15 17:29:36 +00:00
parent a72945b799
commit 07da19144f
2 changed files with 34 additions and 12 deletions

View File

@ -190,8 +190,7 @@ trap(frame)
* interrupts and then trapped. Enabling interrupts * interrupts and then trapped. Enabling interrupts
* now is wrong, but it is better than running with * now is wrong, but it is better than running with
* interrupts disabled until they are accidentally * interrupts disabled until they are accidentally
* enabled later. XXX This is really bad if we trap * enabled later.
* while holding a spin lock.
*/ */
type = frame.tf_trapno; type = frame.tf_trapno;
if (ISPL(frame.tf_cs) == SEL_UPL || (frame.tf_eflags & PSL_VM)) 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", printf("kernel trap %d with interrupts disabled\n",
type); type);
/* /*
* We should walk p_heldmtx here and see if any are * Page faults need interrupts diasabled until later,
* spin mutexes, and not do this if so. * 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 * an interrupt gate for the pagefault handler. We
* are finally ready to read %cr2 and then must * are finally ready to read %cr2 and then must
* reenable interrupts. * 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(); eva = rcr2();
enable_intr(); if (PCPU_GET(spinlocks) == NULL)
enable_intr();
else
trap_fatal(&frame, eva);
} }
if ((ISPL(frame.tf_cs) == SEL_UPL) || if ((ISPL(frame.tf_cs) == SEL_UPL) ||

View File

@ -190,8 +190,7 @@ trap(frame)
* interrupts and then trapped. Enabling interrupts * interrupts and then trapped. Enabling interrupts
* now is wrong, but it is better than running with * now is wrong, but it is better than running with
* interrupts disabled until they are accidentally * interrupts disabled until they are accidentally
* enabled later. XXX This is really bad if we trap * enabled later.
* while holding a spin lock.
*/ */
type = frame.tf_trapno; type = frame.tf_trapno;
if (ISPL(frame.tf_cs) == SEL_UPL || (frame.tf_eflags & PSL_VM)) 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", printf("kernel trap %d with interrupts disabled\n",
type); type);
/* /*
* We should walk p_heldmtx here and see if any are * Page faults need interrupts diasabled until later,
* spin mutexes, and not do this if so. * 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 * an interrupt gate for the pagefault handler. We
* are finally ready to read %cr2 and then must * are finally ready to read %cr2 and then must
* reenable interrupts. * 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(); eva = rcr2();
enable_intr(); if (PCPU_GET(spinlocks) == NULL)
enable_intr();
else
trap_fatal(&frame, eva);
} }
if ((ISPL(frame.tf_cs) == SEL_UPL) || if ((ISPL(frame.tf_cs) == SEL_UPL) ||