summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authorrink <rink@FreeBSD.org>2009-05-27 18:12:27 +0000
committerrink <rink@FreeBSD.org>2009-05-27 18:12:27 +0000
commit1843497c73653aba06fad4b9e766e6e4496c63c8 (patch)
tree059827f60f268f9899124ac79d2a77de2cba18e3 /sys/ia64
parent095c1f19b69905801b4f310ea68c2c805aa56998 (diff)
downloadFreeBSD-src-1843497c73653aba06fad4b9e766e6e4496c63c8.zip
FreeBSD-src-1843497c73653aba06fad4b9e766e6e4496c63c8.tar.gz
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.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/mp_machdep.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c
index 4756dcd..6dba43a 100644
--- a/sys/ia64/ia64/mp_machdep.c
+++ b/sys/ia64/ia64/mp_machdep.c
@@ -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;
OpenPOWER on IntegriCloud