drivers/vfio/virqfd.c
Source file repositories/reference/linux-study-clean/drivers/vfio/virqfd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/vfio/virqfd.c- Extension
.c- Size
- 5553 bytes
- Lines
- 227
- Domain
- Driver Families
- Bucket
- drivers/vfio
- 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.
- 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/vfio.hlinux/eventfd.hlinux/file.hlinux/module.hlinux/slab.hvfio.h
Detected Declarations
function vfio_virqfd_initfunction vfio_virqfd_exitfunction virqfd_deactivatefunction virqfd_wakeupfunction virqfd_ptable_queue_procfunction virqfd_shutdownfunction virqfd_injectfunction virqfd_flush_injectfunction vfio_virqfd_enablefunction vfio_virqfd_disablefunction vfio_virqfd_flush_threadexport vfio_virqfd_enableexport vfio_virqfd_disableexport vfio_virqfd_flush_thread
Annotated Snippet
if (*(virqfd->pvirqfd) == virqfd) {
*(virqfd->pvirqfd) = NULL;
virqfd_deactivate(virqfd);
}
spin_unlock_irqrestore(&virqfd_lock, flags);
}
return 0;
}
static void virqfd_ptable_queue_proc(struct file *file,
wait_queue_head_t *wqh, poll_table *pt)
{
struct virqfd *virqfd = container_of(pt, struct virqfd, pt);
add_wait_queue(wqh, &virqfd->wait);
}
static void virqfd_shutdown(struct work_struct *work)
{
struct virqfd *virqfd = container_of(work, struct virqfd, shutdown);
u64 cnt;
eventfd_ctx_remove_wait_queue(virqfd->eventfd, &virqfd->wait, &cnt);
flush_work(&virqfd->inject);
eventfd_ctx_put(virqfd->eventfd);
kfree(virqfd);
}
static void virqfd_inject(struct work_struct *work)
{
struct virqfd *virqfd = container_of(work, struct virqfd, inject);
if (virqfd->thread)
virqfd->thread(virqfd->opaque, virqfd->data);
}
static void virqfd_flush_inject(struct work_struct *work)
{
struct virqfd *virqfd = container_of(work, struct virqfd, flush_inject);
flush_work(&virqfd->inject);
}
int vfio_virqfd_enable(void *opaque,
int (*handler)(void *, void *),
void (*thread)(void *, void *),
void *data, struct virqfd **pvirqfd, int fd)
{
struct eventfd_ctx *ctx;
struct virqfd *virqfd;
int ret = 0;
__poll_t events;
virqfd = kzalloc_obj(*virqfd, GFP_KERNEL_ACCOUNT);
if (!virqfd)
return -ENOMEM;
virqfd->pvirqfd = pvirqfd;
virqfd->opaque = opaque;
virqfd->handler = handler;
virqfd->thread = thread;
virqfd->data = data;
INIT_WORK(&virqfd->shutdown, virqfd_shutdown);
INIT_WORK(&virqfd->inject, virqfd_inject);
INIT_WORK(&virqfd->flush_inject, virqfd_flush_inject);
CLASS(fd, irqfd)(fd);
if (fd_empty(irqfd)) {
ret = -EBADF;
goto err_fd;
}
ctx = eventfd_ctx_fileget(fd_file(irqfd));
if (IS_ERR(ctx)) {
ret = PTR_ERR(ctx);
goto err_fd;
}
virqfd->eventfd = ctx;
/*
* virqfds can be released by closing the eventfd or directly
* through ioctl. These are both done through a workqueue, so
* we update the pointer to the virqfd under lock to avoid
* pushing multiple jobs to release the same virqfd.
*/
spin_lock_irq(&virqfd_lock);
Annotation
- Immediate include surface: `linux/vfio.h`, `linux/eventfd.h`, `linux/file.h`, `linux/module.h`, `linux/slab.h`, `vfio.h`.
- Detected declarations: `function vfio_virqfd_init`, `function vfio_virqfd_exit`, `function virqfd_deactivate`, `function virqfd_wakeup`, `function virqfd_ptable_queue_proc`, `function virqfd_shutdown`, `function virqfd_inject`, `function virqfd_flush_inject`, `function vfio_virqfd_enable`, `function vfio_virqfd_disable`.
- Atlas domain: Driver Families / drivers/vfio.
- Implementation status: integration implementation candidate.
- 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.