diff options
author | rink <rink@FreeBSD.org> | 2009-05-27 18:12:27 +0000 |
---|---|---|
committer | rink <rink@FreeBSD.org> | 2009-05-27 18:12:27 +0000 |
commit | 1843497c73653aba06fad4b9e766e6e4496c63c8 (patch) | |
tree | 059827f60f268f9899124ac79d2a77de2cba18e3 | |
parent | 095c1f19b69905801b4f310ea68c2c805aa56998 (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/ia64/ia64/mp_machdep.c | 34 |
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; |