svn commit: r344332 - head/sys/x86/x86

Bruce Evans bde at
Wed Feb 20 02:40:39 UTC 2019

Author: bde
Date: Wed Feb 20 02:40:38 2019
New Revision: 344332

  Fix hangs in r341810 waiting for AP startup.
  idle_td is dereferenced without thread-locking it to make its contents is
  invariant, and was accessed without telling the compiler that its contents
  is invariant.  Some compilers optimized accesses to the supposedly invariant
  contents by moving the critical checks for changes outside of the loop that
  waits for changes.  Fix this using atomic ops.
  This bug only showed up for the following configuration: a Turion2
  system, amd64 kernels, compiled by gcc, and SCHED_4BSD.  clang fails
  to do the optimization with all CFLAGS that I tried, because it doesn't
  fully optimize the '__asm __volatile' for cpu_spinwait() although this
  asm has no memory clobber.  gcc only does the optimization with most
  CFLAGS.  I mostly used -Os with all compilers.  i386 works because gcc
  -m32 -Os only moves 1 or the 2 accesses outside of the loop.
  Non-Turion2 systems and SCHED_ULE worked due to different timing (when
  all APs start before the BP checks them outside of the loop).
  Reviewed by:	kib


Modified: head/sys/x86/x86/mp_x86.c
--- head/sys/x86/x86/mp_x86.c	Wed Feb 20 02:14:41 2019	(r344331)
+++ head/sys/x86/x86/mp_x86.c	Wed Feb 20 02:40:38 2019	(r344332)
@@ -1088,8 +1088,8 @@ smp_after_idle_runnable(void *arg __unused)
 	for (cpu = 1; cpu < mp_ncpus; cpu++) {
 		idle_td = pcpu_find(cpu)->pc_idlethread;
-		while (idle_td->td_lastcpu == NOCPU &&
-		    idle_td->td_oncpu == NOCPU)
+		while (atomic_load_int(&idle_td->td_lastcpu) == NOCPU &&
+		    atomic_load_int(&idle_td->td_oncpu) == NOCPU)
 		kmem_free((vm_offset_t)bootstacks[cpu], kstack_pages *

More information about the svn-src-all mailing list