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:          ff326a1879 ("x86: Restore the critical section (...)")
MFC after:      1 week
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D60862
This commit is contained in:
Olivier Certner committed 2026-10-20 18:46:13 +02:00
1 parent b83bd6fec0
commit 3a0e2ca3ee
1 file changed
+12 -13
+12 -13
View File
@@ -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--;
}