Add helper with primary purpose is to efficiently trace a specific physical memory address back to its corresponding TTM buffer object.
v2: - %s/gpu_buddy_addr_to_block/gpu_buddy_allocated_addr_to_block(MattA) - remove clear->avail and split nodes check(MattA) - Adapt lockdep(MattB) Signed-off-by: Tejas Upadhyay <[email protected]> Cc: Arunpravin Paneer Selvam <[email protected]> Cc: [email protected] --- drivers/gpu/buddy.c | 53 +++++++++++++++++++++++++++++++++++++++ include/linux/gpu_buddy.h | 2 ++ 2 files changed, 55 insertions(+) diff --git a/drivers/gpu/buddy.c b/drivers/gpu/buddy.c index eb1457376307..9de9872294a6 100644 --- a/drivers/gpu/buddy.c +++ b/drivers/gpu/buddy.c @@ -594,6 +594,59 @@ void gpu_buddy_free_block(struct gpu_buddy *mm, } EXPORT_SYMBOL(gpu_buddy_free_block); +/** + * gpu_buddy_allocated_addr_to_block - given relative address find the allocated block + * + * @mm: GPU buddy manager + * @addr: Relative address + * + * Returns: + * gpu_buddy_block on success, NULL or error code on failure + */ +struct gpu_buddy_block *gpu_buddy_allocated_addr_to_block(struct gpu_buddy *mm, u64 addr) +{ + struct gpu_buddy_block *block; + LIST_HEAD(dfs); + u64 end; + int i; + + gpu_buddy_driver_lock_held(mm); + + end = addr + SZ_4K - 1; + for (i = 0; i < mm->n_roots; ++i) + list_add_tail(&mm->roots[i]->tmp_link, &dfs); + + do { + u64 block_start; + u64 block_end; + + block = list_first_entry_or_null(&dfs, + struct gpu_buddy_block, + tmp_link); + if (!block) + break; + + list_del(&block->tmp_link); + + block_start = gpu_buddy_block_offset(block); + block_end = block_start + gpu_buddy_block_size(mm, block) - 1; + + if (!overlaps(addr, end, block_start, block_end)) + continue; + + if (gpu_buddy_block_is_allocated(block)) + return block; + else if (gpu_buddy_block_is_free(block)) + return NULL; + + list_add(&block->right->tmp_link, &dfs); + list_add(&block->left->tmp_link, &dfs); + } while (1); + + return ERR_PTR(-ENXIO); +} +EXPORT_SYMBOL(gpu_buddy_allocated_addr_to_block); + static void __gpu_buddy_free_list(struct gpu_buddy *mm, struct list_head *objects, bool mark_clear, diff --git a/include/linux/gpu_buddy.h b/include/linux/gpu_buddy.h index 71941a039648..e7e22fa05ee2 100644 --- a/include/linux/gpu_buddy.h +++ b/include/linux/gpu_buddy.h @@ -272,6 +272,8 @@ void gpu_buddy_reset_clear(struct gpu_buddy *mm, bool is_clear); void gpu_buddy_free_block(struct gpu_buddy *mm, struct gpu_buddy_block *block); +struct gpu_buddy_block *gpu_buddy_allocated_addr_to_block(struct gpu_buddy *mm, u64 addr); + void gpu_buddy_free_list(struct gpu_buddy *mm, struct list_head *objects, unsigned int flags); -- 2.52.0
