Date: Wed, 27 May 2009 18:12:27 +0000 (UTC) From: Rink Springer <rink@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r192918 - head/sys/ia64/ia64 Message-ID: <200905271812.n4RICRJd006978@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905271812.n4RICRJd006978>