git: 4a5d8670a7d5 - main - x86: Close race condition on MCA task queues at startup
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 06 Oct 2025 16:00:17 UTC
The branch main has been updated by jtl: URL: https://cgit.FreeBSD.org/src/commit/?id=4a5d8670a7d58b04913fd90aae85a1e35236ca3d commit 4a5d8670a7d58b04913fd90aae85a1e35236ca3d Author: Jonathan T. Looney <jtl@FreeBSD.org> AuthorDate: 2025-10-03 16:23:07 +0000 Commit: Jonathan T. Looney <jtl@FreeBSD.org> CommitDate: 2025-10-06 15:59:31 +0000 x86: Close race condition on MCA task queues at startup Currently, the CMCI handler checks the cold variable to determine whether it can schedule a task. The task queue is setup as part of the mca_startup() function, which is run well after the configure_final() function sets the cold variable to 0. Therefore, if an MCA arrives in the window between configure_final() and mca_startup() running, the code could try to schedule a task on an unintitalized task queue. Close the race by specifically checking whether the mca_startup() function has run. Reviewed by: markj MFC after: 1 week Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D12276 --- sys/x86/x86/mca.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c index 1851df8d00a0..933d10e52187 100644 --- a/sys/x86/x86/mca.c +++ b/sys/x86/x86/mca.c @@ -133,6 +133,7 @@ static struct taskqueue *mca_tq; static struct task mca_resize_task; static struct timeout_task mca_scan_task; static struct mtx mca_lock; +static bool mca_startup_done = false; /* Statistics on number of MCA events by type, updated atomically. */ static uint64_t mca_stats[MCA_T_COUNT]; @@ -1025,7 +1026,7 @@ mca_process_records(enum scan_mode mode) mtx_unlock_spin(&mca_lock); if (mode == POLLED) mca_resize_freelist(); - else if (!cold) + else if (mca_startup_done) taskqueue_enqueue(mca_tq, &mca_resize_task); } @@ -1097,7 +1098,7 @@ sysctl_mca_maxcount(SYSCTL_HANDLER_ARGS) doresize = true; } mtx_unlock_spin(&mca_lock); - if (doresize && !cold) + if (doresize && mca_startup_done) taskqueue_enqueue(mca_tq, &mca_resize_task); return (error); } @@ -1115,6 +1116,7 @@ mca_startup(void *dummy) taskqueue_start_threads(&mca_tq, 1, PI_SWI(SWI_TQ), "mca taskq"); taskqueue_enqueue_timeout_sbt(mca_tq, &mca_scan_task, mca_ticks * SBT_1S, 0, C_PREL(1)); + mca_startup_done = true; } SYSINIT(mca_startup, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, mca_startup, NULL);