svn commit: r216944 - head/sys/i386/xen

Colin Percival cperciva at FreeBSD.org
Tue Jan 4 00:16:39 UTC 2011


Author: cperciva
Date: Tue Jan  4 00:16:38 2011
New Revision: 216944
URL: http://svn.freebsd.org/changeset/base/216944

Log:
  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.

Modified:
  head/sys/i386/xen/xen_machdep.c

Modified: head/sys/i386/xen/xen_machdep.c
==============================================================================
--- head/sys/i386/xen/xen_machdep.c	Tue Jan  4 00:11:09 2011	(r216943)
+++ head/sys/i386/xen/xen_machdep.c	Tue Jan  4 00:16:38 2011	(r216944)
@@ -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


More information about the svn-src-all mailing list