git: 3a0e2ca3eecd - main - x86: ipi_bitmap_handler(): Account for IPIs correctly on COUNT_IPIS
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 20 Oct 2026 16:47:21 UTC
The branch main has been updated by olce:
URL: https://cgit.FreeBSD.org/src/commit/?id=3a0e2ca3eecd3176fa7dd139e59913a67c858ac9
commit 3a0e2ca3eecd3176fa7dd139e59913a67c858ac9
Author: Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2026-10-13 14:46:26 +0000
Commit: Olivier Certner <olce@FreeBSD.org>
CommitDate: 2026-10-20 16:46:13 +0000
x86: ipi_bitmap_handler(): Account for IPIs correctly on COUNT_IPIS
A preemption could occur before the updates to the initial CPU's IPI
counters, leading to a potential non-atomic updates of these counters
from another CPU.
Reviewed by: kib
Fixes: ff326a187907 ("x86: Restore the critical section (...)")
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60862
---
sys/x86/x86/mp_x86.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index 8fdeff859561..abdc18feb5f8 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -1347,14 +1347,21 @@ ipi_bitmap_handler(struct trapframe *frame)
td->td_intr_nesting_level++;
oldframe = td->td_intr_frame;
td->td_intr_frame = frame;
+
+#ifdef COUNT_IPIS
+ if (ipi_bitmap & (1 << IPI_AST)) {
+ (*ipi_ast_counts[cpu])++;
+ if (ipi_bitmap & (1 << IPI_HARDCLOCK)) {
+ (*ipi_hardclock_counts[cpu])++;
+ if (ipi_bitmap & (1 << IPI_PREEMPT))
+ (*ipi_preempt_counts[cpu])++;
+#endif
+
#if defined(STACK) || defined(DDB)
if (ipi_bitmap & (1 << IPI_TRACE))
stack_capture_intr();
#endif
if (ipi_bitmap & (1 << IPI_HARDCLOCK)) {
-#ifdef COUNT_IPIS
- (*ipi_hardclock_counts[cpu])++;
-#endif
/*
* Enter a critical section so that hardclockintr() can execute
* entirely without preemption (as it calls code that can enter
@@ -1371,9 +1378,6 @@ ipi_bitmap_handler(struct trapframe *frame)
critical_exit();
}
if (ipi_bitmap & (1 << IPI_AST)) {
-#ifdef COUNT_IPIS
- (*ipi_ast_counts[cpu])++;
-#endif
/* Nothing to do for AST */
}
/*
@@ -1382,13 +1386,8 @@ ipi_bitmap_handler(struct trapframe *frame)
* IPIs are processed in due course (in particular, hardclockintr()), it
* has to be called last.
*/
- if (ipi_bitmap & (1 << IPI_PREEMPT)) {
-#ifdef COUNT_IPIS
- (*ipi_preempt_counts[cpu])++;
-#endif
- if (do_preempt)
- sched_preempt(td);
- }
+ if (ipi_bitmap & (1 << IPI_PREEMPT) && do_preempt)
+ sched_preempt(td);
td->td_intr_frame = oldframe;
td->td_intr_nesting_level--;
}