summaryrefslogtreecommitdiffstats
path: root/sys/i386/xen
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2011-01-04 00:16:38 +0000
committercperciva <cperciva@FreeBSD.org>2011-01-04 00:16:38 +0000
commit005e768447a1afdb655d8e7ca8c34c9854140f98 (patch)
tree61579c095ac3e982e81ce6b424c66f1fbc82398c /sys/i386/xen
parenta756c46242b975e3eff37d195fd1cddaef36fa11 (diff)
downloadFreeBSD-src-005e768447a1afdb655d8e7ca8c34c9854140f98.zip
FreeBSD-src-005e768447a1afdb655d8e7ca8c34c9854140f98.tar.gz
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.
Diffstat (limited to 'sys/i386/xen')
-rw-r--r--sys/i386/xen/xen_machdep.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index a9180fc..2a3eade 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -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
OpenPOWER on IntegriCloud