drivers/dma/idxd/device.c
Source file repositories/reference/linux-study-clean/drivers/dma/idxd/device.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/idxd/device.c- Extension
.c- Size
- 41157 bytes
- Lines
- 1652
- Domain
- Driver Families
- Bucket
- drivers/dma
- 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/init.hlinux/kernel.hlinux/module.hlinux/pci.hlinux/io-64-nonatomic-lo-hi.hlinux/dmaengine.hlinux/irq.huapi/linux/idxd.h../dmaengine.hidxd.hregisters.h
Detected Declarations
function idxd_unmask_error_interruptsfunction idxd_mask_error_interruptsfunction free_hw_descsfunction alloc_hw_descsfunction free_descsfunction alloc_descsfunction idxd_wq_alloc_resourcesfunction idxd_wq_free_resourcesfunction idxd_wq_enablefunction idxd_wq_disablefunction idxd_wq_drainfunction idxd_wq_resetfunction idxd_wq_map_portalfunction idxd_wq_unmap_portalfunction idxd_wqs_unmap_portalfunction __idxd_wq_set_pasid_lockedfunction idxd_wq_set_pasidfunction idxd_wq_disable_pasidfunction idxd_wq_disable_cleanupfunction idxd_wq_device_reset_cleanupfunction idxd_wq_ref_releasefunction idxd_wq_init_percpu_reffunction __idxd_wq_quiescefunction idxd_wq_quiescefunction idxd_is_enabledfunction idxd_device_is_haltedfunction idxd_device_init_resetfunction idxd_cmd_execfunction idxd_device_enablefunction idxd_device_disablefunction idxd_device_resetfunction idxd_device_drain_pasidfunction idxd_device_request_int_handlefunction idxd_device_release_int_handlefunction idxd_engines_clear_statefunction idxd_groups_clear_statefunction idxd_device_wqs_clear_statefunction idxd_device_clear_statefunction idxd_device_evl_setupfunction idxd_device_evl_freefunction idxd_group_config_writefunction idxd_groups_config_writefunction idxd_device_pasid_priv_enabledfunction idxd_wq_config_writefunction for_each_set_bitfunction idxd_wqs_config_writefunction idxd_group_flags_setupfunction idxd_engines_setup
Annotated Snippet
if (!wq->hw_descs[i]) {
free_hw_descs(wq);
return -ENOMEM;
}
}
return 0;
}
static void free_descs(struct idxd_wq *wq)
{
int i;
for (i = 0; i < wq->num_descs; i++)
kfree(wq->descs[i]);
kfree(wq->descs);
}
static int alloc_descs(struct idxd_wq *wq, int num)
{
struct device *dev = &wq->idxd->pdev->dev;
int i;
int node = dev_to_node(dev);
wq->descs = kcalloc_node(num, sizeof(struct idxd_desc *),
GFP_KERNEL, node);
if (!wq->descs)
return -ENOMEM;
for (i = 0; i < num; i++) {
wq->descs[i] = kzalloc_node(sizeof(*wq->descs[i]),
GFP_KERNEL, node);
if (!wq->descs[i]) {
free_descs(wq);
return -ENOMEM;
}
}
return 0;
}
/* WQ control bits */
int idxd_wq_alloc_resources(struct idxd_wq *wq)
{
struct idxd_device *idxd = wq->idxd;
struct device *dev = &idxd->pdev->dev;
int rc, num_descs, i;
if (wq->type != IDXD_WQT_KERNEL)
return 0;
num_descs = wq_dedicated(wq) ? wq->size : wq->threshold;
wq->num_descs = num_descs;
rc = alloc_hw_descs(wq, num_descs);
if (rc < 0)
return rc;
wq->compls_size = num_descs * idxd->data->compl_size;
wq->compls = dma_alloc_coherent(dev, wq->compls_size, &wq->compls_addr, GFP_KERNEL);
if (!wq->compls) {
rc = -ENOMEM;
goto fail_alloc_compls;
}
rc = alloc_descs(wq, num_descs);
if (rc < 0)
goto fail_alloc_descs;
rc = sbitmap_queue_init_node(&wq->sbq, num_descs, -1, false, GFP_KERNEL,
dev_to_node(dev));
if (rc < 0)
goto fail_sbitmap_init;
for (i = 0; i < num_descs; i++) {
struct idxd_desc *desc = wq->descs[i];
desc->hw = wq->hw_descs[i];
if (idxd->data->type == IDXD_TYPE_DSA)
desc->completion = &wq->compls[i];
else if (idxd->data->type == IDXD_TYPE_IAX)
desc->iax_completion = &wq->iax_compls[i];
desc->compl_dma = wq->compls_addr + idxd->data->compl_size * i;
desc->id = i;
desc->wq = wq;
desc->cpu = -1;
}
return 0;
Annotation
- Immediate include surface: `linux/init.h`, `linux/kernel.h`, `linux/module.h`, `linux/pci.h`, `linux/io-64-nonatomic-lo-hi.h`, `linux/dmaengine.h`, `linux/irq.h`, `uapi/linux/idxd.h`.
- Detected declarations: `function idxd_unmask_error_interrupts`, `function idxd_mask_error_interrupts`, `function free_hw_descs`, `function alloc_hw_descs`, `function free_descs`, `function alloc_descs`, `function idxd_wq_alloc_resources`, `function idxd_wq_free_resources`, `function idxd_wq_enable`, `function idxd_wq_disable`.
- Atlas domain: Driver Families / drivers/dma.
- 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.