drivers/infiniband/hw/usnic/usnic_uiom.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/usnic/usnic_uiom.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/usnic/usnic_uiom.c- Extension
.c- Size
- 14117 bytes
- Lines
- 553
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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/mm.hlinux/dma-mapping.hlinux/sched/signal.hlinux/sched/mm.hlinux/hugetlb.hlinux/iommu.hlinux/workqueue.hlinux/list.hrdma/ib_verbs.husnic_log.husnic_uiom.husnic_uiom_interval_tree.h
Detected Declarations
function Copyrightfunction usnic_uiom_put_pagesfunction list_for_each_entry_safefunction usnic_uiom_get_pagesfunction for_each_sgfunction usnic_uiom_unmap_sorted_intervalsfunction list_for_each_entry_safefunction __usnic_uiom_reg_releasefunction list_for_each_entry_safefunction usnic_uiom_map_sorted_intervalsfunction __usnic_uiom_release_tailfunction usnic_uiom_num_pagesfunction usnic_uiom_reg_releasefunction usnic_uiom_dealloc_pdfunction usnic_uiom_attach_dev_to_pdfunction usnic_uiom_detach_dev_from_pdfunction list_for_each_entryfunction usnic_uiom_free_dev_list
Annotated Snippet
for_each_sg(chunk->page_list, sg, chunk->nents, i) {
page = sg_page(sg);
pa = sg_phys(sg);
unpin_user_pages_dirty_lock(&page, 1, dirty);
usnic_dbg("pa: %pa\n", &pa);
}
kfree(chunk);
}
}
static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
int dmasync, struct usnic_uiom_reg *uiomr)
{
struct list_head *chunk_list = &uiomr->chunk_list;
unsigned int gup_flags = FOLL_LONGTERM;
struct page **page_list;
struct scatterlist *sg;
struct usnic_uiom_chunk *chunk;
unsigned long locked;
unsigned long lock_limit;
unsigned long cur_base;
unsigned long npages;
int ret;
int off;
int i;
dma_addr_t pa;
struct mm_struct *mm;
/*
* If the combination of the addr and size requested for this memory
* region causes an integer overflow, return error.
*/
if (((addr + size) < addr) || PAGE_ALIGN(addr + size) < (addr + size))
return -EINVAL;
if (!size)
return -EINVAL;
if (!can_do_mlock())
return -EPERM;
INIT_LIST_HEAD(chunk_list);
page_list = (struct page **) __get_free_page(GFP_KERNEL);
if (!page_list)
return -ENOMEM;
npages = PAGE_ALIGN(size + (addr & ~PAGE_MASK)) >> PAGE_SHIFT;
uiomr->owning_mm = mm = current->mm;
mmap_read_lock(mm);
locked = atomic64_add_return(npages, ¤t->mm->pinned_vm);
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
ret = -ENOMEM;
goto out;
}
if (writable)
gup_flags |= FOLL_WRITE;
cur_base = addr & PAGE_MASK;
ret = 0;
while (npages) {
ret = pin_user_pages(cur_base,
min_t(unsigned long, npages,
PAGE_SIZE / sizeof(struct page *)),
gup_flags, page_list);
if (ret < 0)
goto out;
npages -= ret;
off = 0;
while (ret) {
chunk = kmalloc_flex(*chunk, page_list,
min_t(int, ret, USNIC_UIOM_PAGE_CHUNK));
if (!chunk) {
ret = -ENOMEM;
goto out;
}
chunk->nents = min_t(int, ret, USNIC_UIOM_PAGE_CHUNK);
sg_init_table(chunk->page_list, chunk->nents);
for_each_sg(chunk->page_list, sg, chunk->nents, i) {
sg_set_page(sg, page_list[i + off],
PAGE_SIZE, 0);
Annotation
- Immediate include surface: `linux/mm.h`, `linux/dma-mapping.h`, `linux/sched/signal.h`, `linux/sched/mm.h`, `linux/hugetlb.h`, `linux/iommu.h`, `linux/workqueue.h`, `linux/list.h`.
- Detected declarations: `function Copyright`, `function usnic_uiom_put_pages`, `function list_for_each_entry_safe`, `function usnic_uiom_get_pages`, `function for_each_sg`, `function usnic_uiom_unmap_sorted_intervals`, `function list_for_each_entry_safe`, `function __usnic_uiom_reg_release`, `function list_for_each_entry_safe`, `function usnic_uiom_map_sorted_intervals`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source 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.