drivers/infiniband/hw/mlx4/mr.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mlx4/mr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/mlx4/mr.c- Extension
.c- Size
- 11714 bytes
- Lines
- 470
- 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 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/slab.hrdma/ib_user_verbs.hrdma/iter.hmlx4_ib.h
Detected Declarations
function Copyrightfunction to_mlx4_typefunction mlx4_ib_umem_write_mttfunction rdma_umem_for_each_dma_blockfunction mlx4_alloc_priv_pagesfunction mlx4_free_priv_pagesfunction mlx4_ib_dereg_mrfunction mlx4_ib_alloc_mwfunction mlx4_ib_dealloc_mwfunction mlx4_set_pagefunction mlx4_ib_map_mr_sg
Annotated Snippet
if (IS_ERR(mmr->umem)) {
err = PTR_ERR(mmr->umem);
/* Prevent mlx4_ib_dereg_mr from free'ing invalid pointer */
mmr->umem = NULL;
goto release_mpt_entry;
}
n = ib_umem_num_dma_blocks(mmr->umem, PAGE_SIZE);
shift = PAGE_SHIFT;
err = mlx4_mr_rereg_mem_write(dev->dev, &mmr->mmr,
virt_addr, length, n, shift,
*pmpt_entry);
if (err) {
ib_umem_release(mmr->umem);
goto release_mpt_entry;
}
mmr->mmr.iova = virt_addr;
mmr->mmr.size = length;
err = mlx4_ib_umem_write_mtt(dev, &mmr->mmr.mtt, mmr->umem);
if (err) {
mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr);
ib_umem_release(mmr->umem);
goto release_mpt_entry;
}
}
/* If we couldn't transfer the MR to the HCA, just remember to
* return a failure. But dereg_mr will free the resources.
*/
err = mlx4_mr_hw_write_mpt(dev->dev, &mmr->mmr, pmpt_entry);
if (!err && flags & IB_MR_REREG_ACCESS) {
mmr->access_flags = mr_access_flags;
mmr->mmr.access = convert_access(mr_access_flags);
}
release_mpt_entry:
mlx4_mr_hw_put_mpt(dev->dev, pmpt_entry);
if (err)
return ERR_PTR(err);
return NULL;
}
static int
mlx4_alloc_priv_pages(struct ib_device *device,
struct mlx4_ib_mr *mr,
int max_pages)
{
int ret;
/* Ensure that size is aligned to DMA cacheline
* requirements.
* max_pages is limited to MLX4_MAX_FAST_REG_PAGES
* so page_map_size will never cross PAGE_SIZE.
*/
mr->page_map_size = roundup(max_pages * sizeof(u64),
MLX4_MR_PAGES_ALIGN);
/* Prevent cross page boundary allocation. */
mr->pages = (__be64 *)get_zeroed_page(GFP_KERNEL);
if (!mr->pages)
return -ENOMEM;
mr->page_map = dma_map_single(device->dev.parent, mr->pages,
mr->page_map_size, DMA_TO_DEVICE);
if (dma_mapping_error(device->dev.parent, mr->page_map)) {
ret = -ENOMEM;
goto err;
}
return 0;
err:
free_page((unsigned long)mr->pages);
return ret;
}
static void
mlx4_free_priv_pages(struct mlx4_ib_mr *mr)
{
if (mr->pages) {
struct ib_device *device = mr->ibmr.device;
dma_unmap_single(device->dev.parent, mr->page_map,
mr->page_map_size, DMA_TO_DEVICE);
free_page((unsigned long)mr->pages);
mr->pages = NULL;
}
}
Annotation
- Immediate include surface: `linux/slab.h`, `rdma/ib_user_verbs.h`, `rdma/iter.h`, `mlx4_ib.h`.
- Detected declarations: `function Copyright`, `function to_mlx4_type`, `function mlx4_ib_umem_write_mtt`, `function rdma_umem_for_each_dma_block`, `function mlx4_alloc_priv_pages`, `function mlx4_free_priv_pages`, `function mlx4_ib_dereg_mr`, `function mlx4_ib_alloc_mw`, `function mlx4_ib_dealloc_mw`, `function mlx4_set_page`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source implementation candidate.
- 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.