- 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:
parent
a72945b799
commit
07da19144f
@ -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) ||
|
||||||
|
@ -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) ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user