drivers/infiniband/hw/hfi1/pin_system.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/pin_system.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/hfi1/pin_system.c- Extension
.c- Size
- 12668 bytes
- Lines
- 475
- 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/types.hhfi.hcommon.hdevice.hpinning.hmmu_rb.huser_sdma.htrace.h
Detected Declarations
struct sdma_mmu_nodefunction hfi1_init_system_pinningfunction hfi1_free_system_pinningfunction sdma_cache_evictfunction unpin_vector_pagesfunction free_system_nodefunction kref_getfunction pin_system_pagesfunction kref_initfunction get_system_cache_entryfunction sdma_mmu_rb_node_getfunction sdma_mmu_rb_node_putfunction add_mapping_to_sdma_packetfunction add_system_iovec_to_sdma_packetfunction hfi1_add_pages_to_sdma_packetfunction sdma_rb_filterfunction sdma_rb_evictfunction sdma_rb_remove
Annotated Snippet
struct sdma_mmu_node {
struct mmu_rb_node rb;
struct hfi1_user_sdma_pkt_q *pq;
struct page **pages;
unsigned int npages;
};
static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
unsigned long len);
static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode, void *arg2,
bool *stop);
static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode);
static const struct mmu_rb_ops sdma_rb_ops = {
.filter = sdma_rb_filter,
.evict = sdma_rb_evict,
.remove = sdma_rb_remove,
};
int hfi1_init_system_pinning(struct hfi1_user_sdma_pkt_q *pq)
{
struct hfi1_devdata *dd = pq->dd;
int ret;
ret = hfi1_mmu_rb_register(pq, &sdma_rb_ops, dd->pport->hfi1_wq,
&pq->handler);
if (ret)
dd_dev_err(dd,
"[%u:%u] Failed to register system memory DMA support with MMU: %d\n",
pq->ctxt, pq->subctxt, ret);
return ret;
}
void hfi1_free_system_pinning(struct hfi1_user_sdma_pkt_q *pq)
{
if (pq->handler)
hfi1_mmu_rb_unregister(pq->handler);
}
static u32 sdma_cache_evict(struct hfi1_user_sdma_pkt_q *pq, u32 npages)
{
struct evict_data evict_data;
evict_data.cleared = 0;
evict_data.target = npages;
hfi1_mmu_rb_evict(pq->handler, &evict_data);
return evict_data.cleared;
}
static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
unsigned int start, unsigned int npages)
{
hfi1_release_user_pages(mm, pages + start, npages, false);
kfree(pages);
}
static inline struct mm_struct *mm_from_sdma_node(struct sdma_mmu_node *node)
{
return node->rb.handler->mn.mm;
}
static void free_system_node(struct sdma_mmu_node *node)
{
if (node->npages) {
unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0,
node->npages);
atomic_sub(node->npages, &node->pq->n_locked);
}
kfree(node);
}
/*
* kref_get()'s an additional kref on the returned rb_node to prevent rb_node
* from being released until after rb_node is assigned to an SDMA descriptor
* (struct sdma_desc) under add_system_iovec_to_sdma_packet(), even if the
* virtual address range for rb_node is invalidated between now and then.
*/
static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler,
unsigned long start,
unsigned long end)
{
struct mmu_rb_node *rb_node;
unsigned long flags;
spin_lock_irqsave(&handler->lock, flags);
rb_node = hfi1_mmu_rb_get_first(handler, start, (end - start));
if (!rb_node) {
spin_unlock_irqrestore(&handler->lock, flags);
return NULL;
}
Annotation
- Immediate include surface: `linux/types.h`, `hfi.h`, `common.h`, `device.h`, `pinning.h`, `mmu_rb.h`, `user_sdma.h`, `trace.h`.
- Detected declarations: `struct sdma_mmu_node`, `function hfi1_init_system_pinning`, `function hfi1_free_system_pinning`, `function sdma_cache_evict`, `function unpin_vector_pages`, `function free_system_node`, `function kref_get`, `function pin_system_pages`, `function kref_init`, `function get_system_cache_entry`.
- 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.