/* SPDX-License-Identifier: GPL-2.0 */ /* * IRQ subsystem internal functions and variables: * * Do not ever include this file from anything else than * kernel/irq/. Do not even think about using any information outside * of this file for your non core code.
*/ #include <linux/irqdesc.h> #include <linux/kernel_stat.h> #include <linux/pm_runtime.h> #include <linux/sched/clock.h>
/* * Bits used by threaded handlers: * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run * IRQTF_WARNED - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed * IRQTF_AFFINITY - irq thread is requested to adjust affinity * IRQTF_FORCED_THREAD - irq action is force threaded * IRQTF_READY - signals that irq thread is ready
*/ enum {
IRQTF_RUNTHREAD,
IRQTF_WARNED,
IRQTF_AFFINITY,
IRQTF_FORCED_THREAD,
IRQTF_READY,
};
/* * Bit masks for desc->core_internal_state__do_not_mess_with_it * * IRQS_AUTODETECT - autodetection in progress * IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt * detection * IRQS_POLL_INPROGRESS - polling in progress * IRQS_ONESHOT - irq is not unmasked in primary handler * IRQS_REPLAY - irq has been resent and will not be resent * again until the handler has run and cleared * this flag. * IRQS_WAITING - irq is waiting * IRQS_PENDING - irq needs to be resent and should be resent * at the next available opportunity. * IRQS_SUSPENDED - irq is suspended * IRQS_NMI - irq line is used to deliver NMIs * IRQS_SYSFS - descriptor has been added to sysfs
*/ enum {
IRQS_AUTODETECT = 0x00000001,
IRQS_SPURIOUS_DISABLED = 0x00000002,
IRQS_POLL_INPROGRESS = 0x00000008,
IRQS_ONESHOT = 0x00000020,
IRQS_REPLAY = 0x00000040,
IRQS_WAITING = 0x00000080,
IRQS_PENDING = 0x00000200,
IRQS_SUSPENDED = 0x00000800,
IRQS_TIMINGS = 0x00001000,
IRQS_NMI = 0x00002000,
IRQS_SYSFS = 0x00004000,
};
/* Inline functions for support of irq chips on slow busses */ staticinlinevoid chip_bus_lock(struct irq_desc *desc)
{ if (unlikely(desc->irq_data.chip->irq_bus_lock))
desc->irq_data.chip->irq_bus_lock(&desc->irq_data);
}
staticinlinevoid chip_bus_sync_unlock(struct irq_desc *desc)
{ if (unlikely(desc->irq_data.chip->irq_bus_sync_unlock))
desc->irq_data.chip->irq_bus_sync_unlock(&desc->irq_data);
}
/** * struct irq_timings - irq timings storing structure * @values: a circular buffer of u64 encoded <timestamp,irq> values * @count: the number of elements in the array
*/ struct irq_timings {
u64 values[IRQ_TIMINGS_SIZE]; int count;
};
staticinlinevoid irq_setup_timings(struct irq_desc *desc, struct irqaction *act)
{ int irq = irq_desc_get_irq(desc); int ret;
/* * We don't need the measurement because the idle code already * knows the next expiry event.
*/ if (act->flags & __IRQF_TIMER) return;
/* * In case the timing allocation fails, we just want to warn, * not fail, so letting the system boot anyway.
*/
ret = irq_timings_alloc(irq); if (ret) {
pr_warn("Failed to allocate irq timing stats for irq%d (%d)",
irq, ret); return;
}
/* * The interrupt number and the timestamp are encoded into a single * u64 variable to optimize the size. * 48 bit time stamp and 16 bit IRQ number is way sufficient. * Who cares an IRQ after 78 hours of idle time?
*/ staticinline u64 irq_timing_encode(u64 timestamp, int irq)
{ return (timestamp << 16) | irq;
}
staticinlineint irq_timing_decode(u64 value, u64 *timestamp)
{
*timestamp = value >> 16; return value & U16_MAX;
}
/* * The function record_irq_time is only called in one place in the * interrupts handler. We want this function always inline so the code * inside is embedded in the function and the static key branching * code can act at the higher level. Without the explicit * __always_inline we can end up with a function call and a small * overhead in the hotpath for nothing.
*/ static __always_inline void record_irq_time(struct irq_desc *desc)
{ if (!static_branch_likely(&irq_timing_enabled)) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.