drivers/dma/idxd/cdev.c
Source file repositories/reference/linux-study-clean/drivers/dma/idxd/cdev.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/idxd/cdev.c- Extension
.c- Size
- 18830 bytes
- Lines
- 784
- Domain
- Driver Families
- Bucket
- drivers/dma
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/device.hlinux/sched/task.hlinux/io-64-nonatomic-lo-hi.hlinux/cdev.hlinux/fs.hlinux/poll.hlinux/iommu.hlinux/highmem.huapi/linux/idxd.hlinux/xarray.hregisters.hidxd.h
Detected Declarations
struct idxd_cdev_contextstruct idxd_user_contextfunction cr_faults_showfunction cr_fault_failures_showfunction pid_showfunction cdev_file_attr_visiblefunction idxd_file_dev_releasefunction idxd_cdev_dev_releasefunction idxd_xa_pasid_removefunction idxd_user_counter_incrementfunction idxd_cdev_openfunction idxd_cdev_evl_drain_pasidfunction idxd_cdev_releasefunction check_vmafunction idxd_cdev_mmapfunction idxd_submit_user_descriptorfunction idxd_cdev_writefunction idxd_cdev_pollfunction idxd_cdev_get_majorfunction idxd_wq_add_cdevfunction idxd_wq_del_cdevfunction idxd_user_drv_probefunction idxd_user_drv_removefunction idxd_cdev_registerfunction idxd_cdev_removefunction idxd_copy_crexport idxd_user_drv
Annotated Snippet
static const struct file_operations idxd_cdev_fops = {
.owner = THIS_MODULE,
.open = idxd_cdev_open,
.release = idxd_cdev_release,
.mmap = idxd_cdev_mmap,
.write = idxd_cdev_write,
.poll = idxd_cdev_poll,
};
int idxd_cdev_get_major(struct idxd_device *idxd)
{
return MAJOR(ictx[idxd->data->type].devt);
}
int idxd_wq_add_cdev(struct idxd_wq *wq)
{
struct idxd_device *idxd = wq->idxd;
struct idxd_cdev *idxd_cdev;
struct cdev *cdev;
struct device *dev;
struct idxd_cdev_context *cdev_ctx;
int rc, minor;
idxd_cdev = kzalloc_obj(*idxd_cdev);
if (!idxd_cdev)
return -ENOMEM;
idxd_cdev->idxd_dev.type = IDXD_DEV_CDEV;
idxd_cdev->wq = wq;
cdev = &idxd_cdev->cdev;
dev = cdev_dev(idxd_cdev);
cdev_ctx = &ictx[wq->idxd->data->type];
minor = ida_alloc_max(&cdev_ctx->minor_ida, MINORMASK, GFP_KERNEL);
if (minor < 0) {
kfree(idxd_cdev);
return minor;
}
idxd_cdev->minor = minor;
device_initialize(dev);
dev->parent = wq_confdev(wq);
dev->bus = &dsa_bus_type;
dev->type = &idxd_cdev_device_type;
dev->devt = MKDEV(MAJOR(cdev_ctx->devt), minor);
rc = dev_set_name(dev, "%s/wq%u.%u", idxd->data->name_prefix, idxd->id, wq->id);
if (rc < 0)
goto err;
wq->idxd_cdev = idxd_cdev;
cdev_init(cdev, &idxd_cdev_fops);
rc = cdev_device_add(cdev, dev);
if (rc) {
dev_dbg(&wq->idxd->pdev->dev, "cdev_add failed: %d\n", rc);
goto err;
}
return 0;
err:
put_device(dev);
wq->idxd_cdev = NULL;
return rc;
}
void idxd_wq_del_cdev(struct idxd_wq *wq)
{
struct idxd_cdev_context *cdev_ctx;
struct idxd_cdev *idxd_cdev;
idxd_cdev = wq->idxd_cdev;
wq->idxd_cdev = NULL;
cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev));
cdev_ctx = &ictx[wq->idxd->data->type];
ida_free(&cdev_ctx->minor_ida, idxd_cdev->minor);
put_device(cdev_dev(idxd_cdev));
}
static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)
{
struct device *dev = &idxd_dev->conf_dev;
struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
struct idxd_device *idxd = wq->idxd;
int rc;
if (idxd->state != IDXD_DEV_ENABLED)
return -ENXIO;
mutex_lock(&wq->wq_lock);
Annotation
- Immediate include surface: `linux/init.h`, `linux/kernel.h`, `linux/module.h`, `linux/pci.h`, `linux/device.h`, `linux/sched/task.h`, `linux/io-64-nonatomic-lo-hi.h`, `linux/cdev.h`.
- Detected declarations: `struct idxd_cdev_context`, `struct idxd_user_context`, `function cr_faults_show`, `function cr_fault_failures_show`, `function pid_show`, `function cdev_file_attr_visible`, `function idxd_file_dev_release`, `function idxd_cdev_dev_release`, `function idxd_xa_pasid_remove`, `function idxd_user_counter_increment`.
- Atlas domain: Driver Families / drivers/dma.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.