summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python/bin/stackcollapse-record
diff options
context:
space:
mode:
authorBoqun Feng <boqun@kernel.org>2026-08-04 11:26:57 -0700
committerPeter Zijlstra <peterz@infradead.org>2026-08-10 10:50:18 +0200
commite901c1510e24726dcbd6340ee927b3ac8b992043 (patch)
treeb85d761599e8aa15e3c4ca1d4c01c78006d19b62 /tools/perf/scripts/python/bin/stackcollapse-record
parente35e7700029b936356d736d6378cf596019e4cc8 (diff)
irq,spin_lock: Add counted interrupt disabling/enabling
Currently the nested interrupt disabling and enabling is represented by _irqsave() and _irqrestore() APIs, which are relatively unsafe, for example: <interrupts are enabled as beginning> spin_lock_irqsave(l1, flag1); spin_lock_irqsave(l2, flag2); spin_unlock_irqrestore(l1, flags1); <l2 is still held but interrupts are enabled> // accesses to interrupt-disable protected data will cause races This is even easier to trigger with guard facilities: unsigned long flag2; scoped_guard(spin_lock_irqsave, l1) { spin_lock_irqsave(l2, flag2); } // l2 locked but interrupts are enabled. spin_unlock_irqrestore(l2, flag2); (Hand-to-hand locking critical sections are not uncommon for a fine-grained lock design) And because of this unsafety, Rust cannot easily wrap the interrupt-disabling locks in a safe API, which complicates the design. To resolve this, introduce a new set of interrupt disabling APIs: * local_interrupt_disable(); * local_interrupt_enable(); They work like local_irq_save() and local_irq_restore() except that 1) the outermost local_interrupt_disable() call saves the interrupt state into a per-CPU variable, so that the outermost local_interrupt_enable() can restore the state, and 2) a per-CPU counter is added to record the nest level of these calls, so that interrupts are not accidentally enabled inside the outermost critical section. Also add the corresponding spin_lock primitives: spin_lock_irq_disable() and spin_unlock_irq_enable(), as a result, code as follows: spin_lock_irq_disable(l1); spin_lock_irq_disable(l2); spin_unlock_irq_enable(l1); // Interrupts are still disabled. spin_unlock_irq_enable(l2); doesn't have the issue that interrupts are accidentally enabled. This also makes the wrapper of interrupt-disabling locks on Rust easier to design. [boqun: Apply Peter's feedback and fix spell errors reported by Ingo] [boqun: Address the duplicate spin_acquire() spotted by sashiko] Co-developed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Boqun Feng <boqun@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20260804182657.87716-1-boqun@kernel.org
Diffstat (limited to 'tools/perf/scripts/python/bin/stackcollapse-record')
0 files changed, 0 insertions, 0 deletions