drivers/pci/pcie/aer.c
Source file repositories/reference/linux-study-clean/drivers/pci/pcie/aer.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/pcie/aer.c- Extension
.c- Size
- 47834 bytes
- Lines
- 1741
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/bitops.hlinux/cper.hlinux/dev_printk.hlinux/pci.hlinux/pci-acpi.hlinux/sched.hlinux/kernel.hlinux/errno.hlinux/pm.hlinux/init.hlinux/interrupt.hlinux/delay.hlinux/kfifo.hlinux/ratelimit.hlinux/slab.hlinux/vmcore_info.hacpi/apei.hacpi/ghes.hras/ras_event.h../pci.hportdrv.h
Detected Declarations
struct aer_err_sourcestruct aer_rpcstruct aer_infostruct aer_recover_entryfunction pci_no_aerfunction pci_aer_availablefunction enable_ecrc_checkingfunction disable_ecrc_checkingfunction pcie_set_ecrc_checkingfunction pcie_ecrc_get_policyfunction pcie_aer_is_nativefunction pci_enable_pcie_error_reportingfunction pci_aer_clear_nonfatal_statusfunction pci_aer_clear_fatal_statusfunction pci_aer_raw_clear_statusfunction pci_aer_clear_statusfunction pci_save_aer_statefunction pci_restore_aer_statefunction pci_aer_initfunction pci_aer_exitfunction aer_stats_attrs_are_visiblefunction aer_attrs_are_visiblefunction pci_dev_aer_stats_incrfunction pci_rootport_aer_stats_incrfunction aer_ratelimitfunction tlp_header_loggedfunction __aer_print_errorfunction for_each_set_bitfunction aer_print_sourcefunction aer_print_errorfunction cper_severity_to_aerfunction pci_print_aerfunction add_error_devicefunction is_error_sourcefunction find_device_iterfunction find_source_devicefunction pci_aer_unmask_internal_errorsfunction is_aer_internal_errorfunction pci_aer_handle_errorfunction handle_error_sourcefunction aer_recover_work_funcfunction aer_recover_queuefunction aer_get_device_error_infofunction aer_process_err_devicesfunction aer_isr_one_error_typefunction aer_isr_one_errorfunction aer_isrfunction aer_irq
Annotated Snippet
struct pci_driver *pdrv = dev->driver;
if (pdrv && pdrv->err_handler &&
pdrv->err_handler->cor_error_detected)
pdrv->err_handler->cor_error_detected(dev);
pcie_clear_device_status(dev);
}
} else if (info->severity == AER_NONFATAL)
pcie_do_recovery(dev, pci_channel_io_normal, aer_root_reset);
else if (info->severity == AER_FATAL)
pcie_do_recovery(dev, pci_channel_io_frozen, aer_root_reset);
}
static void handle_error_source(struct pci_dev *dev, struct aer_err_info *info)
{
cxl_rch_handle_error(dev, info);
pci_aer_handle_error(dev, info);
pci_dev_put(dev);
}
#ifdef CONFIG_ACPI_APEI_PCIEAER
#define AER_RECOVER_RING_SIZE 16
struct aer_recover_entry {
u8 bus;
u8 devfn;
u16 domain;
int severity;
struct aer_capability_regs *regs;
};
static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry,
AER_RECOVER_RING_SIZE);
static void aer_recover_work_func(struct work_struct *work)
{
struct aer_recover_entry entry;
struct pci_dev *pdev;
while (kfifo_get(&aer_recover_ring, &entry)) {
pdev = pci_get_domain_bus_and_slot(entry.domain, entry.bus,
entry.devfn);
if (!pdev) {
pr_err_ratelimited("%04x:%02x:%02x.%x: no pci_dev found\n",
entry.domain, entry.bus,
PCI_SLOT(entry.devfn),
PCI_FUNC(entry.devfn));
continue;
}
pci_print_aer(pdev, entry.severity, entry.regs);
/*
* Memory for aer_capability_regs(entry.regs) is being
* allocated from the ghes_estatus_pool to protect it from
* overwriting when multiple sections are present in the
* error status. Thus free the same after processing the
* data.
*/
ghes_estatus_pool_region_free((unsigned long)entry.regs,
sizeof(struct aer_capability_regs));
if (entry.severity == AER_NONFATAL)
pcie_do_recovery(pdev, pci_channel_io_normal,
aer_root_reset);
else if (entry.severity == AER_FATAL)
pcie_do_recovery(pdev, pci_channel_io_frozen,
aer_root_reset);
pci_dev_put(pdev);
}
}
/*
* Mutual exclusion for writers of aer_recover_ring, reader side don't
* need lock, because there is only one reader and lock is not needed
* between reader and writer.
*/
static DEFINE_SPINLOCK(aer_recover_ring_lock);
static DECLARE_WORK(aer_recover_work, aer_recover_work_func);
void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
int severity, struct aer_capability_regs *aer_regs)
{
struct aer_recover_entry entry = {
.bus = bus,
.devfn = devfn,
.domain = domain,
.severity = severity,
.regs = aer_regs,
};
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/cper.h`, `linux/dev_printk.h`, `linux/pci.h`, `linux/pci-acpi.h`, `linux/sched.h`, `linux/kernel.h`, `linux/errno.h`.
- Detected declarations: `struct aer_err_source`, `struct aer_rpc`, `struct aer_info`, `struct aer_recover_entry`, `function pci_no_aer`, `function pci_aer_available`, `function enable_ecrc_checking`, `function disable_ecrc_checking`, `function pcie_set_ecrc_checking`, `function pcie_ecrc_get_policy`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: pattern implementation candidate.
- 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.