drivers/pci/p2pdma.c
Source file repositories/reference/linux-study-clean/drivers/pci/p2pdma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/p2pdma.c- Extension
.c- Size
- 32030 bytes
- Lines
- 1210
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: exported/initcall integration point
- Status
- integration 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.
- 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/ctype.hlinux/dma-map-ops.hlinux/pci-p2pdma.hlinux/module.hlinux/slab.hlinux/genalloc.hlinux/memremap.hlinux/percpu-refcount.hlinux/random.hlinux/seq_buf.hlinux/xarray.h
Detected Declarations
struct pci_p2pdmastruct pci_p2pdma_pagemapfunction size_showfunction available_showfunction published_showfunction p2pmem_alloc_mmapfunction vm_insert_pagefunction p2pdma_folio_freefunction pci_p2pdma_releasefunction pcim_p2pdma_initfunction providerfunction pci_p2pdma_setup_poolfunction pci_p2pdma_unmap_mappingsfunction pci_p2pdma_add_resourcefunction pci_bridge_has_acs_redirfunction seq_buf_print_bus_devfnfunction cpu_supports_p2pdmafunction pci_get_slotfunction __host_bridge_whitelistfunction host_bridge_whitelistfunction map_types_idxfunction calc_map_type_and_distfunction pci_upstream_bridgefunction pci_p2pdma_distance_manyfunction pci_has_p2pmemfunction takenfunction for_each_pci_devfunction pci_free_p2pmemfunction pci_alloc_p2pmemfunction pci_p2pmem_free_sglfunction for_each_sgfunction pci_p2pmem_findfunction pci_p2pdma_map_typefunction __pci_p2pdma_update_statefunction devicefunction pci_p2pdma_enable_storeexport pcim_p2pdma_initexport pcim_p2pdma_providerexport pci_p2pdma_add_resourceexport pci_p2pdma_distance_manyexport pci_p2pmem_find_manyexport pci_alloc_p2pmemexport pci_free_p2pmemexport pci_p2pmem_virt_to_busexport pci_p2pmem_alloc_sglexport pci_p2pmem_free_sglexport pci_p2pmem_publishexport pci_p2pdma_enable_store
Annotated Snippet
struct pci_p2pdma {
struct gen_pool *pool;
bool p2pmem_published;
struct xarray map_types;
struct p2pdma_provider mem[PCI_STD_NUM_BARS];
};
struct pci_p2pdma_pagemap {
struct dev_pagemap pgmap;
struct p2pdma_provider *mem;
};
static struct pci_p2pdma_pagemap *to_p2p_pgmap(struct dev_pagemap *pgmap)
{
return container_of(pgmap, struct pci_p2pdma_pagemap, pgmap);
}
static ssize_t size_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_p2pdma *p2pdma;
size_t size = 0;
rcu_read_lock();
p2pdma = rcu_dereference(pdev->p2pdma);
if (p2pdma && p2pdma->pool)
size = gen_pool_size(p2pdma->pool);
rcu_read_unlock();
return sysfs_emit(buf, "%zd\n", size);
}
static DEVICE_ATTR_RO(size);
static ssize_t available_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_p2pdma *p2pdma;
size_t avail = 0;
rcu_read_lock();
p2pdma = rcu_dereference(pdev->p2pdma);
if (p2pdma && p2pdma->pool)
avail = gen_pool_avail(p2pdma->pool);
rcu_read_unlock();
return sysfs_emit(buf, "%zd\n", avail);
}
static DEVICE_ATTR_RO(available);
static ssize_t published_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_p2pdma *p2pdma;
bool published = false;
rcu_read_lock();
p2pdma = rcu_dereference(pdev->p2pdma);
if (p2pdma)
published = p2pdma->p2pmem_published;
rcu_read_unlock();
return sysfs_emit(buf, "%d\n", published);
}
static DEVICE_ATTR_RO(published);
static int p2pmem_alloc_mmap(struct file *filp, struct kobject *kobj,
const struct bin_attribute *attr, struct vm_area_struct *vma)
{
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
size_t len = vma->vm_end - vma->vm_start;
struct pci_p2pdma *p2pdma;
struct percpu_ref *ref;
unsigned long vaddr;
void *kaddr;
int ret;
/* prevent private mappings from being established */
if ((vma->vm_flags & VM_MAYSHARE) != VM_MAYSHARE) {
pci_info_ratelimited(pdev,
"%s: fail, attempted private mapping\n",
current->comm);
return -EINVAL;
}
if (vma->vm_pgoff) {
pci_info_ratelimited(pdev,
"%s: fail, attempted mapping with non-zero offset\n",
Annotation
- Immediate include surface: `linux/ctype.h`, `linux/dma-map-ops.h`, `linux/pci-p2pdma.h`, `linux/module.h`, `linux/slab.h`, `linux/genalloc.h`, `linux/memremap.h`, `linux/percpu-refcount.h`.
- Detected declarations: `struct pci_p2pdma`, `struct pci_p2pdma_pagemap`, `function size_show`, `function available_show`, `function published_show`, `function p2pmem_alloc_mmap`, `function vm_insert_page`, `function p2pdma_folio_free`, `function pci_p2pdma_release`, `function pcim_p2pdma_init`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- 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.