kernel/irq/manage.c

Source file repositories/reference/linux-study-clean/kernel/irq/manage.c

File Facts

System
Linux kernel
Corpus path
kernel/irq/manage.c
Extension
.c
Size
78321 bytes
Lines
2815
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

static inline void synchronize_irqwork(struct irq_desc *desc) { }
#endif

static int __irq_get_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool *state);

static void __synchronize_hardirq(struct irq_desc *desc, bool sync_chip)
{
	struct irq_data *irqd = irq_desc_get_irq_data(desc);
	bool inprogress;

	do {
		/*
		 * Wait until we're out of the critical section.  This might
		 * give the wrong answer due to the lack of memory barriers.
		 */
		while (irqd_irq_inprogress(&desc->irq_data))
			cpu_relax();

		/* Ok, that indicated we're done: double-check carefully. */
		guard(raw_spinlock_irqsave)(&desc->lock);
		inprogress = irqd_irq_inprogress(&desc->irq_data);

		/*
		 * If requested and supported, check at the chip whether it
		 * is in flight at the hardware level, i.e. already pending
		 * in a CPU and waiting for service and acknowledge.
		 */
		if (!inprogress && sync_chip) {
			/*
			 * Ignore the return code. inprogress is only updated
			 * when the chip supports it.
			 */
			__irq_get_irqchip_state(irqd, IRQCHIP_STATE_ACTIVE,
						&inprogress);
		}
		/* Oops, that failed? */
	} while (inprogress);
}

/**
 * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
 * @irq: interrupt number to wait for
 *
 * This function waits for any pending hard IRQ handlers for this interrupt
 * to complete before returning. If you use this function while holding a
 * resource the IRQ handler may need you will deadlock. It does not take
 * associated threaded handlers into account.
 *
 * Do not use this for shutdown scenarios where you must be sure that all
 * parts (hardirq and threaded handler) have completed.
 *
 * Returns: false if a threaded handler is active.
 *
 * This function may be called - with care - from IRQ context.
 *
 * It does not check whether there is an interrupt in flight at the
 * hardware level, but not serviced yet, as this might deadlock when called
 * with interrupts disabled and the target CPU of the interrupt is the
 * current CPU.
 */
bool synchronize_hardirq(unsigned int irq)
{
	struct irq_desc *desc = irq_to_desc(irq);

	if (desc) {
		__synchronize_hardirq(desc, false);
		return !atomic_read(&desc->threads_active);
	}

	return true;
}
EXPORT_SYMBOL(synchronize_hardirq);

static void __synchronize_irq(struct irq_desc *desc)
{
	synchronize_irqwork(desc);
	__synchronize_hardirq(desc, true);

	/*
	 * We made sure that no hardirq handler is running. Now verify that no
	 * threaded handlers are active.
	 */
	wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
}

/**
 * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
 * @irq: interrupt number to wait for
 *
 * This function waits for any pending IRQ handlers for this interrupt to

Annotation

Implementation Notes