Adjust the critical section protecting _xen_flush_queue to cover the
entire range where the page mapping request queue needs to be atomically examined and modified. Oddly, while this doesn't seem to affect the overall rate of panics (running 'make index' on EC2 t1.micro instances, there are 0.6 +/- 0.1 panics per hour, both before and after this change), it eliminates vm_fault from panic backtraces, leaving only backtraces going through vmspace_fork.
This commit is contained in:
parent
763e8c9623
commit
d01b2dad73
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/sysproto.h>
|
||||
|
||||
@ -249,10 +250,13 @@ _xen_flush_queue(void)
|
||||
SET_VCPU();
|
||||
int _xpq_idx = XPQ_IDX;
|
||||
int error, i;
|
||||
/* window of vulnerability here? */
|
||||
|
||||
#ifdef INVARIANTS
|
||||
if (__predict_true(gdtset))
|
||||
critical_enter();
|
||||
KASSERT(curthread->td_critnest > 0,
|
||||
("xen queue flush should be in a critical section"));
|
||||
#endif
|
||||
|
||||
XPQ_IDX = 0;
|
||||
/* Make sure index is cleared first to avoid double updates. */
|
||||
error = HYPERVISOR_mmu_update((mmu_update_t *)&XPQ_QUEUE,
|
||||
@ -286,8 +290,6 @@ _xen_flush_queue(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (__predict_true(gdtset))
|
||||
critical_exit();
|
||||
if (__predict_false(error < 0)) {
|
||||
for (i = 0; i < _xpq_idx; i++)
|
||||
printf("val: %llx ptr: %llx\n",
|
||||
@ -301,7 +303,12 @@ void
|
||||
xen_flush_queue(void)
|
||||
{
|
||||
SET_VCPU();
|
||||
|
||||
if (__predict_true(gdtset))
|
||||
critical_enter();
|
||||
if (XPQ_IDX != 0) _xen_flush_queue();
|
||||
if (__predict_true(gdtset))
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
static __inline void
|
||||
|
Loading…
x
Reference in New Issue
Block a user