drivers/accel/habanalabs/common/memory.c
Source file repositories/reference/linux-study-clean/drivers/accel/habanalabs/common/memory.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/accel/habanalabs/common/memory.c- Extension
.c- Size
- 81462 bytes
- Lines
- 2939
- Domain
- Driver Families
- Bucket
- drivers/accel
- 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
uapi/drm/habanalabs_accel.hhabanalabs.h../include/hw_ip/mmu/mmu_general.hlinux/uaccess.hlinux/slab.hlinux/vmalloc.hlinux/pci-p2pdma.h
Detected Declarations
function set_alloc_page_sizefunction chunksfunction dma_map_host_vafunction dma_unmap_host_vafunction dram_pg_pool_do_releasefunction free_phys_pg_packfunction free_device_memoryfunction clear_va_list_lockedfunction list_for_each_entry_safefunction print_va_list_lockedfunction merge_va_blocks_lockedfunction add_va_block_lockedfunction list_for_each_entryfunction add_va_blockfunction is_hint_crossing_rangefunction get_va_blockfunction do_divfunction list_for_each_entryfunction hl_reserve_va_blockfunction hl_get_va_range_typefunction hl_unreserve_va_blockfunction init_phys_pg_pack_from_userptrfunction map_phys_pg_packfunction unmap_phys_pg_packfunction map_device_vafunction unmap_device_vafunction map_blockfunction hw_block_vm_closefunction hl_hw_block_mmapfunction set_dma_sgfunction for_each_sgtable_dma_sgfunction hl_dmabuf_attachfunction hl_unmap_dmabuffunction memhash_node_export_putfunction hl_release_dmabuffunction export_dmabuffunction validate_export_params_commonfunction validate_export_params_no_mmufunction validate_export_paramsfunction export_dmabuf_from_addrfunction ts_buff_releasefunction hl_ts_mmapfunction hl_ts_alloc_buffunction allocate_timestamps_buffersfunction hl_mem_ioctlfunction get_user_memoryfunction hl_pin_host_memoryfunction PAGE_ALIGN
Annotated Snippet
if (!is_power_of_2(psize)) {
dev_err(hdev->dev, "user page size (%#llx) is not power of 2\n", psize);
return -EINVAL;
}
} else {
psize = prop->device_mem_alloc_default_page_size;
}
*page_size = psize;
return 0;
}
/*
* The va ranges in context object contain a list with the available chunks of
* device virtual memory.
* There is one range for host allocations and one for DRAM allocations.
*
* On initialization each range contains one chunk of all of its available
* virtual range which is a half of the total device virtual range.
*
* On each mapping of physical pages, a suitable virtual range chunk (with a
* minimum size) is selected from the list. If the chunk size equals the
* requested size, the chunk is returned. Otherwise, the chunk is split into
* two chunks - one to return as result and a remainder to stay in the list.
*
* On each Unmapping of a virtual address, the relevant virtual chunk is
* returned to the list. The chunk is added to the list and if its edges match
* the edges of the adjacent chunks (means a contiguous chunk can be created),
* the chunks are merged.
*
* On finish, the list is checked to have only one chunk of all the relevant
* virtual range (which is a half of the device total virtual range).
* If not (means not all mappings were unmapped), a warning is printed.
*/
/*
* alloc_device_memory() - allocate device memory.
* @ctx: pointer to the context structure.
* @args: host parameters containing the requested size.
* @ret_handle: result handle.
*
* This function does the following:
* - Allocate the requested size rounded up to 'dram_page_size' pages.
* - Return unique handle for later map/unmap/free.
*/
static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args,
u32 *ret_handle)
{
struct hl_device *hdev = ctx->hdev;
struct hl_vm *vm = &hdev->vm;
struct hl_vm_phys_pg_pack *phys_pg_pack;
u64 paddr = 0, total_size, num_pgs, i;
u32 num_curr_pgs, page_size;
bool contiguous;
int handle, rc;
num_curr_pgs = 0;
rc = set_alloc_page_size(hdev, args, &page_size);
if (rc)
return rc;
num_pgs = DIV_ROUND_UP_ULL(args->alloc.mem_size, page_size);
total_size = num_pgs * page_size;
if (!total_size) {
dev_err(hdev->dev, "Cannot allocate 0 bytes\n");
return -EINVAL;
}
contiguous = args->flags & HL_MEM_CONTIGUOUS;
if (contiguous) {
if (is_power_of_2(page_size))
paddr = (uintptr_t) gen_pool_dma_alloc_align(vm->dram_pg_pool,
total_size, NULL, page_size);
else
paddr = gen_pool_alloc(vm->dram_pg_pool, total_size);
if (!paddr) {
dev_err(hdev->dev,
"Cannot allocate %llu contiguous pages with total size of %llu\n",
num_pgs, total_size);
return -ENOMEM;
}
}
phys_pg_pack = kzalloc_obj(*phys_pg_pack);
if (!phys_pg_pack) {
rc = -ENOMEM;
Annotation
- Immediate include surface: `uapi/drm/habanalabs_accel.h`, `habanalabs.h`, `../include/hw_ip/mmu/mmu_general.h`, `linux/uaccess.h`, `linux/slab.h`, `linux/vmalloc.h`, `linux/pci-p2pdma.h`.
- Detected declarations: `function set_alloc_page_size`, `function chunks`, `function dma_map_host_va`, `function dma_unmap_host_va`, `function dram_pg_pool_do_release`, `function free_phys_pg_pack`, `function free_device_memory`, `function clear_va_list_locked`, `function list_for_each_entry_safe`, `function print_va_list_locked`.
- Atlas domain: Driver Families / drivers/accel.
- 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.