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; _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"