drivers/infiniband/hw/hfi1/user_exp_rcv.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/user_exp_rcv.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/hfi1/user_exp_rcv.c- Extension
.c- Size
- 27483 bytes
- Lines
- 956
- 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.
- 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.
- 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
asm/page.hlinux/string.hmmu_rb.huser_exp_rcv.htrace.h
Detected Declarations
function hfi1_user_exp_rcv_initfunction hfi1_user_exp_rcv_freefunction mappedfunction pin_rcv_pagesfunction setsfunction list_for_each_entry_safefunction hfi1_user_exp_rcv_clearfunction hfi1_user_exp_rcv_invalidfunction find_phys_blocksfunction program_rcvarrayfunction set_rcvarray_entryfunction unprogram_rcvarrayfunction __clear_tid_nodefunction clear_tid_nodefunction unlock_exp_tidsfunction list_for_each_entry_safefunction tid_rb_invalidatefunction tid_cover_invalidatefunction cacheless_tid_rb_remove
Annotated Snippet
if (!fd->invalid_tids) {
kfree(fd->entry_to_rb);
fd->entry_to_rb = NULL;
return -ENOMEM;
}
fd->use_mn = true;
}
/*
* PSM does not have a good way to separate, count, and
* effectively enforce a limit on RcvArray entries used by
* subctxts (when context sharing is used) when TID caching
* is enabled. To help with that, we calculate a per-process
* RcvArray entry share and enforce that.
* If TID caching is not in use, PSM deals with usage on its
* own. In that case, we allow any subctxt to take all of the
* entries.
*
* Make sure that we set the tid counts only after successful
* init.
*/
spin_lock(&fd->tid_lock);
if (uctxt->subctxt_cnt && fd->use_mn) {
u16 remainder;
fd->tid_limit = uctxt->expected_count / uctxt->subctxt_cnt;
remainder = uctxt->expected_count % uctxt->subctxt_cnt;
if (remainder && fd->subctxt < remainder)
fd->tid_limit++;
} else {
fd->tid_limit = uctxt->expected_count;
}
spin_unlock(&fd->tid_lock);
return ret;
}
void hfi1_user_exp_rcv_free(struct hfi1_filedata *fd)
{
struct hfi1_ctxtdata *uctxt = fd->uctxt;
mutex_lock(&uctxt->exp_mutex);
if (!EXP_TID_SET_EMPTY(uctxt->tid_full_list))
unlock_exp_tids(uctxt, &uctxt->tid_full_list, fd);
if (!EXP_TID_SET_EMPTY(uctxt->tid_used_list))
unlock_exp_tids(uctxt, &uctxt->tid_used_list, fd);
mutex_unlock(&uctxt->exp_mutex);
kfree(fd->invalid_tids);
fd->invalid_tids = NULL;
kfree(fd->entry_to_rb);
fd->entry_to_rb = NULL;
}
/*
* Release pinned receive buffer pages.
*
* @mapped: true if the pages have been DMA mapped. false otherwise.
* @idx: Index of the first page to unpin.
* @npages: No of pages to unpin.
*
* If the pages have been DMA mapped (indicated by mapped parameter), their
* info will be passed via a struct tid_rb_node. If they haven't been mapped,
* their info will be passed via a struct tid_user_buf.
*/
static void unpin_rcv_pages(struct hfi1_filedata *fd,
struct tid_user_buf *tidbuf,
struct tid_rb_node *node,
unsigned int idx,
unsigned int npages,
bool mapped)
{
struct page **pages;
struct hfi1_devdata *dd = fd->uctxt->dd;
struct mm_struct *mm;
if (mapped) {
dma_unmap_single(&dd->pcidev->dev, node->dma_addr,
node->npages * PAGE_SIZE, DMA_FROM_DEVICE);
pages = &node->pages[idx];
mm = mm_from_tid_node(node);
} else {
pages = &tidbuf->pages[idx];
mm = current->mm;
}
hfi1_release_user_pages(mm, pages, npages, mapped);
fd->tid_n_pinned -= npages;
}
Annotation
- Immediate include surface: `asm/page.h`, `linux/string.h`, `mmu_rb.h`, `user_exp_rcv.h`, `trace.h`.
- Detected declarations: `function hfi1_user_exp_rcv_init`, `function hfi1_user_exp_rcv_free`, `function mapped`, `function pin_rcv_pages`, `function sets`, `function list_for_each_entry_safe`, `function hfi1_user_exp_rcv_clear`, `function hfi1_user_exp_rcv_invalid`, `function find_phys_blocks`, `function program_rcvarray`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source 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.
- 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.