Date: Mon, 2 Apr 2012 17:26:21 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r233793 - head/sys/x86/x86 Message-ID: <201204021726.q32HQLVQ007988@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Mon Apr 2 17:26:21 2012 New Revision: 233793 URL: http://svn.freebsd.org/changeset/base/233793 Log: Further tweak the changes made in r233709. The kernel doesn't permit sleeping from a swi handler (even though in this case it would be ok), so switch the refill and scanning SWI handlers to being tasks on a fast taskqueue. Also, only schedule the refill task for a CMCI as an MC# can fire at any time, so it should do the minimal amount of work needed and avoid opportunities to deadlock before it panics (such as scheduling a task it won't ever need in practice). To handle the case of an MC# only finding recoverable errors (which should never happen), always try to refill the event free list when the periodic scan executes. MFC after: 2 weeks Modified: head/sys/x86/x86/mca.c Modified: head/sys/x86/x86/mca.c ============================================================================== --- head/sys/x86/x86/mca.c Mon Apr 2 17:16:24 2012 (r233792) +++ head/sys/x86/x86/mca.c Mon Apr 2 17:26:21 2012 (r233793) @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <sys/sysctl.h> #include <sys/systm.h> +#include <sys/taskqueue.h> #include <machine/intr_machdep.h> #include <machine/apicvar.h> #include <machine/cputypes.h> @@ -108,8 +109,9 @@ static int mca_freecount; static STAILQ_HEAD(, mca_internal) mca_records; static struct callout mca_timer; static int mca_ticks = 3600; /* Check hourly by default. */ +static struct taskqueue *mca_tq; +static struct task mca_refill_task, mca_scan_task; static struct mtx mca_lock; -static void *mca_refill_swi, *mca_scan_swi; #ifdef DEV_APIC static struct cmc_state **cmc_state; /* Indexed by cpuid, bank */ @@ -439,7 +441,7 @@ mca_fill_freelist(void) } static void -mca_refill(void *arg) +mca_refill(void *context, int pending) { mca_fill_freelist(); @@ -464,8 +466,6 @@ mca_record_entry(enum scan_mode mode, co } STAILQ_REMOVE_HEAD(&mca_freelist, link); mca_freecount--; - if (mca_refill_swi != NULL) - swi_sched(mca_refill_swi, 0); } rec->rec = *record; @@ -473,6 +473,8 @@ mca_record_entry(enum scan_mode mode, co STAILQ_INSERT_TAIL(&mca_records, rec, link); mca_count++; mtx_unlock_spin(&mca_lock); + if (mode == CMCI) + taskqueue_enqueue_fast(mca_tq, &mca_refill_task); } #ifdef DEV_APIC @@ -616,12 +618,13 @@ mca_scan(enum scan_mode mode) * them to the console. */ static void -mca_scan_cpus(void *arg) +mca_scan_cpus(void *context, int pending) { struct mca_internal *mca; struct thread *td; int count, cpu; + mca_fill_freelist(); td = curthread; count = 0; thread_lock(td); @@ -649,7 +652,7 @@ static void mca_periodic_scan(void *arg) { - swi_sched(mca_scan_swi, 1); + taskqueue_enqueue_fast(mca_tq, &mca_scan_task); callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, NULL); } @@ -663,23 +666,29 @@ sysctl_mca_scan(SYSCTL_HANDLER_ARGS) if (error) return (error); if (i) - swi_sched(mca_scan_swi, 1); + taskqueue_enqueue_fast(mca_tq, &mca_scan_task); return (0); } static void +mca_createtq(void *dummy) +{ + if (mca_banks <= 0) + return; + + mca_tq = taskqueue_create_fast("mca", M_WAITOK, + taskqueue_thread_enqueue, &mca_tq); + taskqueue_start_threads(&mca_tq, 1, PI_SWI(SWI_TQ), "mca taskq"); +} +SYSINIT(mca_createtq, SI_SUB_CONFIGURE, SI_ORDER_ANY, mca_createtq, NULL); + +static void mca_startup(void *dummy) { - struct intr_event *ie; - if (!mca_enabled || !(cpu_feature & CPUID_MCA)) + if (mca_banks <= 0) return; - ie = NULL; - swi_add(&ie, "mca:scan", mca_scan_cpus, NULL, SWI_TQ, INTR_MPSAFE, - &mca_scan_swi); - swi_add(&ie, "mca:refill", mca_refill, NULL, SWI_TQ, INTR_MPSAFE, - &mca_refill_swi); callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, NULL); } SYSINIT(mca_startup, SI_SUB_SMP, SI_ORDER_ANY, mca_startup, NULL); @@ -718,8 +727,10 @@ mca_setup(uint64_t mcg_cap) mca_banks = mcg_cap & MCG_CAP_COUNT; mtx_init(&mca_lock, "mca", NULL, MTX_SPIN); STAILQ_INIT(&mca_records); + TASK_INIT(&mca_scan_task, 0, mca_scan_cpus, NULL); callout_init(&mca_timer, CALLOUT_MPSAFE); STAILQ_INIT(&mca_freelist); + TASK_INIT(&mca_refill_task, 0, mca_refill, NULL); mca_fill_freelist(); SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "count", CTLFLAG_RD, &mca_count, 0, "Record count");
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204021726.q32HQLVQ007988>