Over a few contexts, we may traverse code using unprotected,
preemption-sensitive accessors such as
percpu() without disabling
preemption specifically, because either one condition is true;
preempt_count() bears either of the
STAGE_MASK bits, which turns preemption off, therefore CPU
migration cannot happen (
debug_smp_processor_id() and preempt
percpu accessors would detect such context properly
if we are running over the context of the root stage’s event log
irq_stage_sync_current()) playing a deferred interrupt, in
which case the virtual interrupt disable bit is set, so no CPU
migration may occur either.
For instance, the following contexts qualify:
clockevents_handle_event(), which should either be called from the
head stage - therefore
STAGE_MASK is set - when the proxy tick
device is active on the CPU,
and/or from the root stage playing a timer interrupt event from the
any IRQ flow handler from kernel/irq/chip.c. When called from
generic_pipeline_irq() for pushing an external event to the
on_pipeline_entry() is true, which indicates that
PIPELINE_MASK is set. When called for playing a deferred interrupt
on the root stage, the virtual interrupt disable bit is set.
IRQF_OOB action flag should NOT be used for testing whether
an interrupt is out-of-band, because out-of-band handling may be
turned on/off dynamically on an IRQ descriptor using
irq_switch_oob(), which would not translate to
set/cleared for the attached action handlers.
irq_is_oob() is the right way to check for out-of-band handling.