arch/s390/pci/pci_irq.c
Source file repositories/reference/linux-study-clean/arch/s390/pci/pci_irq.c
File Facts
- System
- Linux kernel
- Corpus path
arch/s390/pci/pci_irq.c- Extension
.c- Size
- 16323 bytes
- Lines
- 664
- Domain
- Architecture Layer
- Bucket
- arch/s390
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/irq.hlinux/kernel_stat.hlinux/pci.hlinux/msi.hlinux/irqchip/irq-msi-lib.hlinux/smp.hasm/isc.hasm/airq.hasm/tpi.h
Detected Declarations
struct cpu_irq_datafunction zpci_set_airqfunction zpci_clear_airqfunction zpci_set_directed_irqfunction zpci_clear_directed_irqfunction zpci_set_irqfunction zpci_clear_irqfunction zpci_set_irq_affinityfunction zpci_encode_hwirqfunction zpci_decode_hwirq_msi_indexfunction zpci_compose_msi_msgfunction zpci_handle_cpu_local_irqfunction zpci_handle_remote_irqfunction zpci_handle_fallback_irqfunction zpci_directed_irq_handlerfunction zpci_floating_irq_handlerfunction __alloc_airqfunction arch_restore_msi_irqsfunction zpci_msi_teardown_directedfunction zpci_msi_teardown_floatingfunction zpci_msi_teardownfunction zpci_msi_preparefunction zpci_msi_domain_allocfunction zpci_msi_clear_airqfunction zpci_msi_domain_freefunction zpci_init_dev_msi_infofunction zpci_create_parent_msi_domainfunction zpci_remove_parent_msi_domainfunction cpu_enable_directed_irqfunction zpci_directed_irq_initfunction for_each_possible_cpufunction zpci_floating_irq_initfunction zpci_irq_initfunction zpci_irq_exit
Annotated Snippet
struct cpu_irq_data {
call_single_data_t csd;
atomic_t scheduled;
};
static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_irq_data, irq_data);
static void zpci_handle_remote_irq(void *data)
{
atomic_t *scheduled = data;
do {
zpci_handle_cpu_local_irq(false);
} while (atomic_dec_return(scheduled));
}
static void zpci_handle_fallback_irq(void)
{
struct cpu_irq_data *cpu_data;
union zpci_sic_iib iib = {{0}};
unsigned long cpu;
int irqs_on = 0;
for (cpu = 0;;) {
cpu = airq_iv_scan(zpci_sbv, cpu, airq_iv_end(zpci_sbv));
if (cpu == -1UL) {
if (irqs_on++)
/* End of second scan with interrupts on. */
break;
/* First scan complete, re-enable interrupts. */
if (zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, PCI_ISC, &iib))
break;
cpu = 0;
continue;
}
cpu_data = &per_cpu(irq_data, cpu);
if (atomic_inc_return(&cpu_data->scheduled) > 1)
continue;
INIT_CSD(&cpu_data->csd, zpci_handle_remote_irq, &cpu_data->scheduled);
smp_call_function_single_async(cpu, &cpu_data->csd);
}
}
static void zpci_directed_irq_handler(struct airq_struct *airq,
struct tpi_info *tpi_info)
{
bool floating = !tpi_info->directed_irq;
if (floating) {
inc_irq_stat(IRQIO_PCF);
zpci_handle_fallback_irq();
} else {
inc_irq_stat(IRQIO_PCD);
zpci_handle_cpu_local_irq(true);
}
}
static void zpci_floating_irq_handler(struct airq_struct *airq,
struct tpi_info *tpi_info)
{
union zpci_sic_iib iib = {{0}};
struct irq_domain *msi_domain;
irq_hw_number_t hwirq;
unsigned long si, ai;
struct airq_iv *aibv;
int irqs_on = 0;
inc_irq_stat(IRQIO_PCF);
for (si = 0;;) {
/* Scan adapter summary indicator bit vector */
si = airq_iv_scan(zpci_sbv, si, airq_iv_end(zpci_sbv));
if (si == -1UL) {
if (irqs_on++)
/* End of second scan with interrupts on. */
break;
/* First scan complete, re-enable interrupts. */
if (zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, PCI_ISC, &iib))
break;
si = 0;
continue;
}
/* Scan the adapter interrupt vector for this device. */
aibv = zpci_ibv[si];
for (ai = 0;;) {
ai = airq_iv_scan(aibv, ai, airq_iv_end(aibv));
if (ai == -1UL)
break;
inc_irq_stat(IRQIO_MSI);
airq_iv_lock(aibv, ai);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/irq.h`, `linux/kernel_stat.h`, `linux/pci.h`, `linux/msi.h`, `linux/irqchip/irq-msi-lib.h`, `linux/smp.h`, `asm/isc.h`.
- Detected declarations: `struct cpu_irq_data`, `function zpci_set_airq`, `function zpci_clear_airq`, `function zpci_set_directed_irq`, `function zpci_clear_directed_irq`, `function zpci_set_irq`, `function zpci_clear_irq`, `function zpci_set_irq_affinity`, `function zpci_encode_hwirq`, `function zpci_decode_hwirq_msi_index`.
- Atlas domain: Architecture Layer / arch/s390.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.