svn commit: r192918 - head/sys/ia64/ia64

Rink Springer rink at FreeBSD.org
Wed May 27 18:12:28 UTC 2009


Author: rink
Date: Wed May 27 18:12:27 2009
New Revision: 192918
URL: http://svn.freebsd.org/changeset/base/192918

Log:
  ia64: Move MCA information retrieval to a per-CPU kthread
  
  Once AP's are launched, their MCA state information is stored and later obtainable using a sysctl. Since the size of the MCA state information is unknown, it will be malloc'ed as needed. However, when 'ia64_ap_startup' runs, it's not yet safe to call malloc and this may cause 'panic: blockable sleep lock (sleep mutex) 8192 @ /usr/src/sys/vm/uma_core.c'. This commit avoids this issue by scheduling a separate kthread to obtain this information, which immediately terminates afterwards.

Modified:
  head/sys/ia64/ia64/mp_machdep.c

Modified: head/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- head/sys/ia64/ia64/mp_machdep.c	Wed May 27 18:12:10 2009	(r192917)
+++ head/sys/ia64/ia64/mp_machdep.c	Wed May 27 18:12:27 2009	(r192918)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/ktr.h>
 #include <sys/proc.h>
 #include <sys/bus.h>
+#include <sys/kthread.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
@@ -89,6 +90,28 @@ cpu_topo(void)
 	return smp_topo_none();
 }
 
+static void
+ia64_store_mca_state(void* arg)
+{
+	unsigned int ncpu = (unsigned int)(uintptr_t)arg;
+	struct thread* td;
+
+	/* ia64_mca_save_state() is CPU-sensitive, so bind ourself to our target CPU */
+	td = curthread;
+	thread_lock(td);
+	sched_bind(td, ncpu);
+	thread_unlock(td);
+
+	/*
+	 * Get and save the CPU specific MCA records. Should we get the
+	 * MCA state for each processor, or just the CMC state?
+	 */
+	ia64_mca_save_state(SAL_INFO_MCA);
+	ia64_mca_save_state(SAL_INFO_CMC);
+
+	kproc_exit(0);
+}
+
 void
 ia64_ap_startup(void)
 {
@@ -118,13 +141,6 @@ ia64_ap_startup(void)
 	KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
 	PCPU_SET(curthread, PCPU_GET(idlethread));
 
-	/*
-	 * Get and save the CPU specific MCA records. Should we get the
-	 * MCA state for each processor, or just the CMC state?
-	 */
-	ia64_mca_save_state(SAL_INFO_MCA);
-	ia64_mca_save_state(SAL_INFO_CMC);
-
 	atomic_add_int(&ap_awake, 1);
 	while (!smp_started)
 		cpu_spinwait();
@@ -285,8 +301,10 @@ cpu_mp_unleash(void *dummy)
 	smp_cpus = 0;
 	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
 		cpus++;
-		if (pc->pc_awake)
+		if (pc->pc_awake) {
+			kproc_create(ia64_store_mca_state, (void*)((uintptr_t)pc->pc_cpuid), NULL, 0, 0, "mca %u", pc->pc_cpuid);
 			smp_cpus++;
+		}
 	}
 
 	ap_awake = 1;


More information about the svn-src-all mailing list