drivers/infiniband/core/umem_dmabuf.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/core/umem_dmabuf.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/core/umem_dmabuf.c- Extension
.c- Size
- 9867 bytes
- Lines
- 363
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- 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.
- 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/dma-buf.hlinux/dma-resv.hlinux/dma-mapping.hlinux/module.huverbs.h
Detected Declarations
function ib_umem_dmabuf_map_pagesfunction ib_umem_dmabuf_unmap_pagesfunction ib_umem_dmabuf_get_with_dma_devicefunction ib_umem_dmabuf_revoke_lockedfunction ib_umem_dmabuf_get_pinned_and_lockfunction ib_umem_dmabuf_get_pinned_with_dma_devicefunction ib_umem_dmabuf_set_revoke_lockedfunction ib_umem_dmabuf_set_revoke_lockedfunction ib_umem_dmabuf_revoke_lockfunction ib_umem_dmabuf_revoke_unlockfunction ib_umem_dmabuf_revokefunction ib_umem_dmabuf_releaseexport ib_umem_dmabuf_map_pagesexport ib_umem_dmabuf_unmap_pagesexport ib_umem_dmabuf_getexport ib_umem_dmabuf_get_pinned_with_dma_deviceexport ib_umem_dmabuf_get_pinned_revocable_and_lockexport ib_umem_dmabuf_set_revoke_lockedexport ib_umem_dmabuf_get_pinnedexport ib_umem_dmabuf_revoke_lockexport ib_umem_dmabuf_revoke_unlockexport ib_umem_dmabuf_revoke
Annotated Snippet
if (cur <= start && start < cur + sg_dma_len(sg)) {
unsigned long offset = start - cur;
umem_dmabuf->first_sg = sg;
umem_dmabuf->first_sg_offset = offset;
sg_dma_address(sg) += offset;
sg_dma_len(sg) -= offset;
cur += offset;
}
if (cur < end && end <= cur + sg_dma_len(sg)) {
unsigned long trim = cur + sg_dma_len(sg) - end;
umem_dmabuf->last_sg = sg;
umem_dmabuf->last_sg_trim = trim;
sg_dma_len(sg) -= trim;
break;
}
cur += sg_dma_len(sg);
}
umem_dmabuf->umem.sgt_append.sgt.sgl = umem_dmabuf->first_sg;
umem_dmabuf->umem.sgt_append.sgt.nents = nmap;
umem_dmabuf->sgt = sgt;
wait_fence:
/*
* Although the sg list is valid now, the content of the pages
* may be not up-to-date. Wait for the exporter to finish
* the migration.
*/
ret = dma_resv_wait_timeout(umem_dmabuf->attach->dmabuf->resv,
DMA_RESV_USAGE_KERNEL,
false, MAX_SCHEDULE_TIMEOUT);
if (ret < 0)
return ret;
if (ret == 0)
return -ETIMEDOUT;
return 0;
}
EXPORT_SYMBOL(ib_umem_dmabuf_map_pages);
void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf)
{
dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
if (!umem_dmabuf->sgt)
return;
/* retore the original sg list */
if (umem_dmabuf->first_sg) {
sg_dma_address(umem_dmabuf->first_sg) -=
umem_dmabuf->first_sg_offset;
sg_dma_len(umem_dmabuf->first_sg) +=
umem_dmabuf->first_sg_offset;
umem_dmabuf->first_sg = NULL;
umem_dmabuf->first_sg_offset = 0;
}
if (umem_dmabuf->last_sg) {
sg_dma_len(umem_dmabuf->last_sg) +=
umem_dmabuf->last_sg_trim;
umem_dmabuf->last_sg = NULL;
umem_dmabuf->last_sg_trim = 0;
}
dma_buf_unmap_attachment(umem_dmabuf->attach, umem_dmabuf->sgt,
DMA_BIDIRECTIONAL);
umem_dmabuf->sgt = NULL;
}
EXPORT_SYMBOL(ib_umem_dmabuf_unmap_pages);
static struct ib_umem_dmabuf *
ib_umem_dmabuf_get_with_dma_device(struct ib_device *device,
struct device *dma_device,
unsigned long offset, size_t size,
int fd, int access,
const struct dma_buf_attach_ops *ops)
{
struct dma_buf *dmabuf;
struct ib_umem_dmabuf *umem_dmabuf;
struct ib_umem *umem;
unsigned long end;
struct ib_umem_dmabuf *ret = ERR_PTR(-EINVAL);
if (check_add_overflow(offset, (unsigned long)size, &end))
return ret;
dmabuf = dma_buf_get(fd);
if (IS_ERR(dmabuf))
return ERR_CAST(dmabuf);
Annotation
- Immediate include surface: `linux/dma-buf.h`, `linux/dma-resv.h`, `linux/dma-mapping.h`, `linux/module.h`, `uverbs.h`.
- Detected declarations: `function ib_umem_dmabuf_map_pages`, `function ib_umem_dmabuf_unmap_pages`, `function ib_umem_dmabuf_get_with_dma_device`, `function ib_umem_dmabuf_revoke_locked`, `function ib_umem_dmabuf_get_pinned_and_lock`, `function ib_umem_dmabuf_get_pinned_with_dma_device`, `function ib_umem_dmabuf_set_revoke_locked`, `function ib_umem_dmabuf_set_revoke_locked`, `function ib_umem_dmabuf_revoke_lock`, `function ib_umem_dmabuf_revoke_unlock`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: integration implementation candidate.
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.