drivers/iommu/dma-iommu.c
Source file repositories/reference/linux-study-clean/drivers/iommu/dma-iommu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/dma-iommu.c- Extension
.c- Size
- 63115 bytes
- Lines
- 2266
- Domain
- Driver Families
- Bucket
- drivers/iommu
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/acpi_iort.hlinux/atomic.hlinux/crash_dump.hlinux/device.hlinux/dma-direct.hlinux/dma-map-ops.hlinux/generic_pt/iommu.hlinux/gfp.hlinux/huge_mm.hlinux/iommu.hlinux/iommu-dma.hlinux/iova.hlinux/irq.hlinux/list_sort.hlinux/memremap.hlinux/mm.hlinux/mutex.hlinux/msi.hlinux/of_iommu.hlinux/pci.hlinux/pci-p2pdma.hlinux/scatterlist.hlinux/spinlock.hlinux/swiotlb.hlinux/vmalloc.htrace/events/swiotlb.hdma-iommu.hiommu-pages.h
Detected Declarations
struct iommu_dma_msi_pagestruct iommu_dma_optionsstruct iommu_dma_cookiestruct iommu_dma_msi_cookiestruct iova_fq_entrystruct iova_fqstruct dma_sgt_handleenum iommu_dma_queue_typefunction iommu_dma_forcedac_setupfunction fq_fullfunction fq_ring_addfunction fq_ring_free_lockedfunction fq_ring_for_eachfunction fq_ring_freefunction fq_flush_iotlbfunction fq_flush_timeoutfunction queue_iovafunction iommu_dma_free_fq_singlefunction iommu_dma_free_fq_percpufunction iommu_dma_free_fqfunction iommu_dma_init_one_fqfunction iommu_dma_init_fq_singlefunction iommu_dma_init_fq_percpufunction iommu_dma_init_fqfunction iommu_get_dma_cookiefunction iommu_get_msi_cookiefunction iommu_put_dma_cookiefunction iommu_put_msi_cookiefunction iommu_dma_get_resv_regionsfunction cookie_init_hw_msi_regionfunction iommu_dma_ranges_sortfunction iova_reserve_pci_windowsfunction resource_list_for_each_entryfunction iova_reserve_iommu_regionsfunction dev_is_untrustedfunction dev_use_swiotlbfunction dev_use_sg_swiotlbfunction kmallocfunction iommu_dma_init_optionsfunction iommu_domain_supports_fqfunction iommu_dma_init_domainfunction dma_info_to_protfunction iommu_dma_alloc_iovafunction iommu_dma_free_iovafunction __iommu_dma_unmapfunction __iommu_dma_mapfunction __iommu_dma_free_pagesfunction iommu_dma_free_noncontiguous
Annotated Snippet
struct iommu_dma_msi_page {
struct list_head list;
dma_addr_t iova;
phys_addr_t phys;
};
enum iommu_dma_queue_type {
IOMMU_DMA_OPTS_PER_CPU_QUEUE,
IOMMU_DMA_OPTS_SINGLE_QUEUE,
};
struct iommu_dma_options {
enum iommu_dma_queue_type qt;
size_t fq_size;
unsigned int fq_timeout;
};
struct iommu_dma_cookie {
struct iova_domain iovad;
struct list_head msi_page_list;
/* Flush queue */
union {
struct iova_fq *single_fq;
struct iova_fq __percpu *percpu_fq;
};
/* Number of TLB flushes that have been started */
atomic64_t fq_flush_start_cnt;
/* Number of TLB flushes that have been finished */
atomic64_t fq_flush_finish_cnt;
/* Timer to regularily empty the flush queues */
struct timer_list fq_timer;
/* 1 when timer is active, 0 when not */
atomic_t fq_timer_on;
/* Domain for flush queue callback; NULL if flush queue not in use */
struct iommu_domain *fq_domain;
/* Options for dma-iommu use */
struct iommu_dma_options options;
};
struct iommu_dma_msi_cookie {
dma_addr_t msi_iova;
struct list_head msi_page_list;
};
static DEFINE_STATIC_KEY_FALSE(iommu_deferred_attach_enabled);
bool iommu_dma_forcedac __read_mostly;
static int __init iommu_dma_forcedac_setup(char *str)
{
int ret = kstrtobool(str, &iommu_dma_forcedac);
if (!ret && iommu_dma_forcedac)
pr_info("Forcing DAC for PCI devices\n");
return ret;
}
early_param("iommu.forcedac", iommu_dma_forcedac_setup);
/* Number of entries per flush queue */
#define IOVA_DEFAULT_FQ_SIZE 256
#define IOVA_SINGLE_FQ_SIZE 32768
/* Timeout (in ms) after which entries are flushed from the queue */
#define IOVA_DEFAULT_FQ_TIMEOUT 10
#define IOVA_SINGLE_FQ_TIMEOUT 1000
/* Flush queue entry for deferred flushing */
struct iova_fq_entry {
unsigned long iova_pfn;
unsigned long pages;
struct iommu_pages_list freelist;
u64 counter; /* Flush counter when this entry was added */
};
/* Per-CPU flush queue structure */
struct iova_fq {
spinlock_t lock;
unsigned int head, tail;
unsigned int mod_mask;
struct iova_fq_entry entries[];
};
#define fq_ring_for_each(i, fq) \
for ((i) = (fq)->head; (i) != (fq)->tail; (i) = ((i) + 1) & (fq)->mod_mask)
static inline bool fq_full(struct iova_fq *fq)
{
assert_spin_locked(&fq->lock);
return (((fq->tail + 1) & fq->mod_mask) == fq->head);
}
Annotation
- Immediate include surface: `linux/acpi_iort.h`, `linux/atomic.h`, `linux/crash_dump.h`, `linux/device.h`, `linux/dma-direct.h`, `linux/dma-map-ops.h`, `linux/generic_pt/iommu.h`, `linux/gfp.h`.
- Detected declarations: `struct iommu_dma_msi_page`, `struct iommu_dma_options`, `struct iommu_dma_cookie`, `struct iommu_dma_msi_cookie`, `struct iova_fq_entry`, `struct iova_fq`, `struct dma_sgt_handle`, `enum iommu_dma_queue_type`, `function iommu_dma_forcedac_setup`, `function fq_full`.
- Atlas domain: Driver Families / drivers/iommu.
- Implementation status: integration 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.