mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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:
1 file changed
+12
-13
+12
-13
@@ -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--;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user