diff options
author | Siddharth Kapoor <ksiddharth@google.com> | 2022-03-15 20:55:10 +0800 |
---|---|---|
committer | Siddharth Kapoor <ksiddharth@google.com> | 2022-03-23 23:13:16 +0800 |
commit | 0b2458bd7089baefcf19906e32dffec3cf6af500 (patch) | |
tree | 61beb8549e7bb3d2582268e2aa982d79b98e2548 /mali_kbase/mali_kbase_mem.c | |
parent | 3d9f70261b023712c5113fb715f114ad8db9cfae (diff) | |
parent | 88d7d984fed1c2a4358ce2bbc334e82d71e3a391 (diff) | |
download | gpu-0b2458bd7089baefcf19906e32dffec3cf6af500.tar.gz |
Merge r36p0 from upstream into android-gs-pixel-5.10-gs101
Bug: 220942030
Test: boot to Home, Camera, Video, Chrome
Signed-off-by: Siddharth Kapoor <ksiddharth@google.com>
Change-Id: I8cf3a6243b092a05299acf956f5293facd1ed3cc
Diffstat (limited to 'mali_kbase/mali_kbase_mem.c')
-rw-r--r-- | mali_kbase/mali_kbase_mem.c | 387 |
1 files changed, 305 insertions, 82 deletions
diff --git a/mali_kbase/mali_kbase_mem.c b/mali_kbase/mali_kbase_mem.c index 7ab2d0b..b494cca 100644 --- a/mali_kbase/mali_kbase_mem.c +++ b/mali_kbase/mali_kbase_mem.c @@ -20,7 +20,7 @@ */ /** - * Base kernel memory APIs + * DOC: Base kernel memory APIs */ #include <linux/dma-buf.h> #include <linux/kernel.h> @@ -104,12 +104,24 @@ static struct rb_root *kbase_gpu_va_to_rbtree(struct kbase_context *kctx, u64 gpu_pfn) { struct rb_root *rbtree = NULL; - struct kbase_reg_zone *exec_va_zone = - kbase_ctx_reg_zone_get(kctx, KBASE_REG_ZONE_EXEC_VA); - /* The gpu_pfn can only be greater than the starting pfn of the EXEC_VA - * zone if this has been initialized. - */ + struct kbase_reg_zone *exec_va_zone = kbase_ctx_reg_zone_get(kctx, KBASE_REG_ZONE_EXEC_VA); + +#if MALI_USE_CSF + struct kbase_reg_zone *fixed_va_zone = + kbase_ctx_reg_zone_get(kctx, KBASE_REG_ZONE_FIXED_VA); + + struct kbase_reg_zone *exec_fixed_va_zone = + kbase_ctx_reg_zone_get(kctx, KBASE_REG_ZONE_EXEC_FIXED_VA); + + if (gpu_pfn >= fixed_va_zone->base_pfn) { + rbtree = &kctx->reg_rbtree_fixed; + return rbtree; + } else if (gpu_pfn >= exec_fixed_va_zone->base_pfn) { + rbtree = &kctx->reg_rbtree_exec_fixed; + return rbtree; + } +#endif if (gpu_pfn >= exec_va_zone->base_pfn) rbtree = &kctx->reg_rbtree_exec; else { @@ -350,7 +362,8 @@ static struct kbase_va_region *kbase_region_tracker_find_region_meeting_reqs( } /** - * Remove a region object from the global list. + * kbase_remove_va_region - Remove a region object from the global list. + * * @kbdev: The kbase device * @reg: Region object to remove * @@ -478,6 +491,8 @@ KBASE_EXPORT_TEST_API(kbase_remove_va_region); * @at_reg: The region to replace * @start_pfn: The Page Frame Number to insert at * @nr_pages: The number of pages of the region + * + * Return: 0 on success, error code otherwise. */ static int kbase_insert_va_region_nolock(struct kbase_va_region *new_reg, struct kbase_va_region *at_reg, u64 start_pfn, size_t nr_pages) @@ -551,6 +566,8 @@ static int kbase_insert_va_region_nolock(struct kbase_va_region *new_reg, * @addr: the address to insert the region at * @nr_pages: the number of pages in the region * @align: the minimum alignment in pages + * + * Return: 0 on success, error code otherwise. */ int kbase_add_va_region(struct kbase_context *kctx, struct kbase_va_region *reg, u64 addr, @@ -567,12 +584,19 @@ int kbase_add_va_region(struct kbase_context *kctx, lockdep_assert_held(&kctx->reg_lock); - /* The executable allocation from the SAME_VA zone would already have an + /* The executable allocation from the SAME_VA zone should already have an * appropriately aligned GPU VA chosen for it. - * Also the executable allocation from EXEC_VA zone doesn't need the - * special alignment. + * Also, executable allocations from EXEC_VA don't need the special + * alignment. */ +#if MALI_USE_CSF + /* The same is also true for the EXEC_FIXED_VA zone. + */ +#endif if (!(reg->flags & KBASE_REG_GPU_NX) && !addr && +#if MALI_USE_CSF + ((reg->flags & KBASE_REG_ZONE_MASK) != KBASE_REG_ZONE_EXEC_FIXED_VA) && +#endif ((reg->flags & KBASE_REG_ZONE_MASK) != KBASE_REG_ZONE_EXEC_VA)) { if (cpu_va_bits > gpu_pc_bits) { align = max(align, (size_t)((1ULL << gpu_pc_bits) @@ -604,15 +628,17 @@ KBASE_EXPORT_TEST_API(kbase_add_va_region); /** * kbase_add_va_region_rbtree - Insert a region into its corresponding rbtree * - * Insert a region into the rbtree that was specified when the region was - * created. If addr is 0 a free area in the rbtree is used, otherwise the - * specified address is used. - * * @kbdev: The kbase device * @reg: The region to add * @addr: The address to add the region at, or 0 to map at any available address * @nr_pages: The size of the region in pages * @align: The minimum alignment in pages + * + * Insert a region into the rbtree that was specified when the region was + * created. If addr is 0 a free area in the rbtree is used, otherwise the + * specified address is used. + * + * Return: 0 on success, error code otherwise. */ int kbase_add_va_region_rbtree(struct kbase_device *kbdev, struct kbase_va_region *reg, @@ -699,6 +725,59 @@ exit: /* * @brief Initialize the internal region tracker data structure. */ +#if MALI_USE_CSF +static void kbase_region_tracker_ds_init(struct kbase_context *kctx, + struct kbase_va_region *same_va_reg, + struct kbase_va_region *custom_va_reg, + struct kbase_va_region *exec_va_reg, + struct kbase_va_region *exec_fixed_va_reg, + struct kbase_va_region *fixed_va_reg) +{ + u64 last_zone_end_pfn; + + kctx->reg_rbtree_same = RB_ROOT; + kbase_region_tracker_insert(same_va_reg); + + last_zone_end_pfn = same_va_reg->start_pfn + same_va_reg->nr_pages; + + /* Although custom_va_reg doesn't always exist, initialize + * unconditionally because of the mem_view debugfs + * implementation which relies on it being empty. + */ + kctx->reg_rbtree_custom = RB_ROOT; + kctx->reg_rbtree_exec = RB_ROOT; + + if (custom_va_reg) { + WARN_ON(custom_va_reg->start_pfn < last_zone_end_pfn); + kbase_region_tracker_insert(custom_va_reg); + last_zone_end_pfn = custom_va_reg->start_pfn + custom_va_reg->nr_pages; + } + + /* Initialize exec, fixed and exec_fixed. These are always + * initialized at this stage, if they will exist at all. + */ + kctx->reg_rbtree_fixed = RB_ROOT; + kctx->reg_rbtree_exec_fixed = RB_ROOT; + + if (exec_va_reg) { + WARN_ON(exec_va_reg->start_pfn < last_zone_end_pfn); + kbase_region_tracker_insert(exec_va_reg); + last_zone_end_pfn = exec_va_reg->start_pfn + exec_va_reg->nr_pages; + } + + if (exec_fixed_va_reg) { + WARN_ON(exec_fixed_va_reg->start_pfn < last_zone_end_pfn); + kbase_region_tracker_insert(exec_fixed_va_reg); + last_zone_end_pfn = exec_fixed_va_reg->start_pfn + exec_fixed_va_reg->nr_pages; + } + + if (fixed_va_reg) { + WARN_ON(fixed_va_reg->start_pfn < last_zone_end_pfn); + kbase_region_tracker_insert(fixed_va_reg); + last_zone_end_pfn = fixed_va_reg->start_pfn + fixed_va_reg->nr_pages; + } +} +#else static void kbase_region_tracker_ds_init(struct kbase_context *kctx, struct kbase_va_region *same_va_reg, struct kbase_va_region *custom_va_reg) @@ -719,6 +798,7 @@ static void kbase_region_tracker_ds_init(struct kbase_context *kctx, if (custom_va_reg) kbase_region_tracker_insert(custom_va_reg); } +#endif /* MALI_USE_CSF */ static void kbase_region_tracker_erase_rbtree(struct rb_root *rbtree) { @@ -753,6 +833,9 @@ void kbase_region_tracker_term(struct kbase_context *kctx) kbase_region_tracker_erase_rbtree(&kctx->reg_rbtree_exec); #if MALI_USE_CSF WARN_ON(!list_empty(&kctx->csf.event_pages_head)); + kbase_region_tracker_erase_rbtree(&kctx->reg_rbtree_exec_fixed); + kbase_region_tracker_erase_rbtree(&kctx->reg_rbtree_fixed); + #endif kbase_gpu_vm_unlock(kctx); } @@ -764,8 +847,8 @@ void kbase_region_tracker_term_rbtree(struct rb_root *rbtree) static size_t kbase_get_same_va_bits(struct kbase_context *kctx) { - return min(kbase_get_num_cpu_va_bits(kctx), - (size_t) kctx->kbdev->gpu_props.mmu.va_bits); + return min_t(size_t, kbase_get_num_cpu_va_bits(kctx), + kctx->kbdev->gpu_props.mmu.va_bits); } int kbase_region_tracker_init(struct kbase_context *kctx) @@ -774,15 +857,38 @@ int kbase_region_tracker_init(struct kbase_context *kctx) struct kbase_va_region *custom_va_reg = NULL; size_t same_va_bits = kbase_get_same_va_bits(kctx); u64 custom_va_size = KBASE_REG_ZONE_CUSTOM_VA_SIZE; - u64 gpu_va_limit = (1ULL << kctx->kbdev->gpu_props.mmu.va_bits) >> PAGE_SHIFT; + u64 gpu_va_bits = kctx->kbdev->gpu_props.mmu.va_bits; + u64 gpu_va_limit = (1ULL << gpu_va_bits) >> PAGE_SHIFT; u64 same_va_pages; u64 same_va_base = 1u; int err; +#if MALI_USE_CSF + struct kbase_va_region *exec_va_reg; + struct kbase_va_region *exec_fixed_va_reg; + struct kbase_va_region *fixed_va_reg; + + u64 exec_va_base; + u64 fixed_va_end; + u64 exec_fixed_va_base; + u64 fixed_va_base; + u64 fixed_va_pages; +#endif /* Take the lock as kbase_free_alloced_region requires it */ kbase_gpu_vm_lock(kctx); same_va_pages = (1ULL << (same_va_bits - PAGE_SHIFT)) - same_va_base; + +#if MALI_USE_CSF + if ((same_va_base + same_va_pages) > KBASE_REG_ZONE_EXEC_VA_BASE_64) { + /* Depending on how the kernel is configured, it's possible (eg on aarch64) for + * same_va_bits to reach 48 bits. Cap same_va_pages so that the same_va zone + * doesn't cross into the exec_va zone. + */ + same_va_pages = KBASE_REG_ZONE_EXEC_VA_BASE_64 - same_va_base; + } +#endif + /* all have SAME_VA */ same_va_reg = kbase_alloc_free_region(&kctx->reg_rbtree_same, same_va_base, @@ -827,6 +933,69 @@ int kbase_region_tracker_init(struct kbase_context *kctx) custom_va_size = 0; } #endif + +#if MALI_USE_CSF + /* The position of EXEC_VA depends on whether the client is 32-bit or 64-bit. */ + exec_va_base = KBASE_REG_ZONE_EXEC_VA_BASE_64; + + /* Similarly the end of the FIXED_VA zone also depends on whether the client + * is 32 or 64-bits. + */ + fixed_va_end = KBASE_REG_ZONE_FIXED_VA_END_64; + +#if IS_ENABLED(CONFIG_64BIT) + if (kbase_ctx_flag(kctx, KCTX_COMPAT)) { + exec_va_base = KBASE_REG_ZONE_EXEC_VA_BASE_32; + fixed_va_end = KBASE_REG_ZONE_FIXED_VA_END_32; + } +#endif + + kbase_ctx_reg_zone_init(kctx, KBASE_REG_ZONE_EXEC_VA, exec_va_base, + KBASE_REG_ZONE_EXEC_VA_SIZE); + + exec_va_reg = kbase_alloc_free_region(&kctx->reg_rbtree_exec, exec_va_base, + KBASE_REG_ZONE_EXEC_VA_SIZE, KBASE_REG_ZONE_EXEC_VA); + + if (!exec_va_reg) { + err = -ENOMEM; + goto fail_free_custom_va; + } + + exec_fixed_va_base = exec_va_base + KBASE_REG_ZONE_EXEC_VA_SIZE; + + kbase_ctx_reg_zone_init(kctx, KBASE_REG_ZONE_EXEC_FIXED_VA, exec_fixed_va_base, + KBASE_REG_ZONE_EXEC_FIXED_VA_SIZE); + + exec_fixed_va_reg = + kbase_alloc_free_region(&kctx->reg_rbtree_exec_fixed, exec_fixed_va_base, + KBASE_REG_ZONE_EXEC_FIXED_VA_SIZE, + KBASE_REG_ZONE_EXEC_FIXED_VA); + + if (!exec_fixed_va_reg) { + err = -ENOMEM; + goto fail_free_exec_va; + } + + fixed_va_base = exec_fixed_va_base + KBASE_REG_ZONE_EXEC_FIXED_VA_SIZE; + fixed_va_pages = fixed_va_end - fixed_va_base; + + kbase_ctx_reg_zone_init(kctx, KBASE_REG_ZONE_FIXED_VA, fixed_va_base, fixed_va_pages); + + fixed_va_reg = kbase_alloc_free_region(&kctx->reg_rbtree_fixed, fixed_va_base, + fixed_va_pages, KBASE_REG_ZONE_FIXED_VA); + + kctx->gpu_va_end = fixed_va_end; + + if (!fixed_va_reg) { + err = -ENOMEM; + goto fail_free_exec_fixed_va; + } + + kbase_region_tracker_ds_init(kctx, same_va_reg, custom_va_reg, exec_va_reg, + exec_fixed_va_reg, fixed_va_reg); + + INIT_LIST_HEAD(&kctx->csf.event_pages_head); +#else /* EXEC_VA zone's codepaths are slightly easier when its base_pfn is * initially U64_MAX */ @@ -834,17 +1003,23 @@ int kbase_region_tracker_init(struct kbase_context *kctx) /* Other zones are 0: kbase_create_context() uses vzalloc */ kbase_region_tracker_ds_init(kctx, same_va_reg, custom_va_reg); - kctx->gpu_va_end = same_va_base + same_va_pages + custom_va_size; - kctx->jit_va = false; - -#if MALI_USE_CSF - INIT_LIST_HEAD(&kctx->csf.event_pages_head); #endif + kctx->jit_va = false; kbase_gpu_vm_unlock(kctx); return 0; +#if MALI_USE_CSF +fail_free_exec_fixed_va: + kbase_free_alloced_region(exec_fixed_va_reg); +fail_free_exec_va: + kbase_free_alloced_region(exec_va_reg); +fail_free_custom_va: + if (custom_va_reg) + kbase_free_alloced_region(custom_va_reg); +#endif + fail_free_same_va: kbase_free_alloced_region(same_va_reg); fail_unlock: @@ -874,7 +1049,9 @@ bool kbase_has_exec_va_zone(struct kbase_context *kctx) } /** - * Determine if any allocations have been made on a context's region tracker + * kbase_region_tracker_has_allocs - Determine if any allocations have been made + * on a context's region tracker + * * @kctx: KBase context * * Check the context to determine if any allocations have been made yet from @@ -1081,6 +1258,7 @@ exit_unlock: int kbase_region_tracker_init_exec(struct kbase_context *kctx, u64 exec_va_pages) { +#if !MALI_USE_CSF struct kbase_va_region *exec_va_reg; struct kbase_reg_zone *exec_va_zone; struct kbase_reg_zone *target_zone; @@ -1089,6 +1267,7 @@ int kbase_region_tracker_init_exec(struct kbase_context *kctx, u64 exec_va_pages unsigned long target_zone_bits; u64 exec_va_start; int err; +#endif /* The EXEC_VA zone shall be created by making space either: * - for 64-bit clients, at the end of the process's address space @@ -1102,6 +1281,12 @@ int kbase_region_tracker_init_exec(struct kbase_context *kctx, u64 exec_va_pages if (exec_va_pages == 0 || exec_va_pages > KBASE_REG_ZONE_EXEC_VA_MAX_PAGES) return -EINVAL; +#if MALI_USE_CSF + /* For CSF GPUs we now setup the EXEC_VA zone during initialization, + * so this request is a null-op. + */ + return 0; +#else kbase_gpu_vm_lock(kctx); /* Verify that we've not already created a EXEC_VA zone, and that the @@ -1187,6 +1372,7 @@ int kbase_region_tracker_init_exec(struct kbase_context *kctx, u64 exec_va_pages exit_unlock: kbase_gpu_vm_unlock(kctx); return err; +#endif /* MALI_USE_CSF */ } #if MALI_USE_CSF @@ -1331,7 +1517,8 @@ void kbase_mem_term(struct kbase_device *kbdev) KBASE_EXPORT_TEST_API(kbase_mem_term); /** - * Allocate a free region object. + * kbase_alloc_free_region - Allocate a free region object. + * * @rbtree: Backlink to the red-black tree of memory regions. * @start_pfn: The Page Frame Number in GPU virtual address space. * @nr_pages: The size of the region in pages. @@ -1342,6 +1529,7 @@ KBASE_EXPORT_TEST_API(kbase_mem_term); * * zone is KBASE_REG_ZONE_CUSTOM_VA or KBASE_REG_ZONE_SAME_VA. * + * Return: pointer to the allocated region object on success, NULL otherwise. */ struct kbase_va_region *kbase_alloc_free_region(struct rb_root *rbtree, u64 start_pfn, size_t nr_pages, int zone) @@ -1399,6 +1587,14 @@ static struct kbase_context *kbase_reg_flags_to_kctx( kctx = container_of(rbtree, struct kbase_context, reg_rbtree_exec); break; +#if MALI_USE_CSF + case KBASE_REG_ZONE_EXEC_FIXED_VA: + kctx = container_of(rbtree, struct kbase_context, reg_rbtree_exec_fixed); + break; + case KBASE_REG_ZONE_FIXED_VA: + kctx = container_of(rbtree, struct kbase_context, reg_rbtree_fixed); + break; +#endif default: WARN(1, "Unknown zone in region: flags=0x%lx\n", reg->flags); break; @@ -1408,7 +1604,8 @@ static struct kbase_context *kbase_reg_flags_to_kctx( } /** - * Free a region object. + * kbase_free_alloced_region - Free a region object. + * * @reg: Region * * The described region must be freed of any mapping. @@ -1630,30 +1827,33 @@ int kbase_gpu_munmap(struct kbase_context *kctx, struct kbase_va_region *reg) if (!reg->gpu_alloc) return -EINVAL; - /* Tear down down GPU page tables, depending on memory type. */ + /* Tear down GPU page tables, depending on memory type. */ switch (reg->gpu_alloc->type) { case KBASE_MEM_TYPE_ALIAS: { - size_t i = 0; - struct kbase_mem_phy_alloc *alloc = reg->gpu_alloc; - - /* Due to the way the number of valid PTEs and ATEs are tracked - * currently, only the GPU virtual range that is backed & mapped - * should be passed to the kbase_mmu_teardown_pages() function, - * hence individual aliased regions needs to be unmapped - * separately. - */ - for (i = 0; i < alloc->imported.alias.nents; i++) { - if (alloc->imported.alias.aliased[i].alloc) { - err = kbase_mmu_teardown_pages( - kctx->kbdev, &kctx->mmu, - reg->start_pfn + - (i * - alloc->imported.alias.stride), - alloc->imported.alias.aliased[i].length, - kctx->as_nr); + size_t i = 0; + struct kbase_mem_phy_alloc *alloc = reg->gpu_alloc; + + /* Due to the way the number of valid PTEs and ATEs are tracked + * currently, only the GPU virtual range that is backed & mapped + * should be passed to the kbase_mmu_teardown_pages() function, + * hence individual aliased regions needs to be unmapped + * separately. + */ + for (i = 0; i < alloc->imported.alias.nents; i++) { + if (alloc->imported.alias.aliased[i].alloc) { + int err_loop = kbase_mmu_teardown_pages( + kctx->kbdev, &kctx->mmu, + reg->start_pfn + + (i * + alloc->imported.alias.stride), + alloc->imported.alias.aliased[i].length, + kctx->as_nr); + if (WARN_ON_ONCE(err_loop)) + err = err_loop; + } } } - } break; + break; case KBASE_MEM_TYPE_IMPORTED_UMM: err = kbase_mmu_teardown_pages(kctx->kbdev, &kctx->mmu, reg->start_pfn, reg->nr_pages, kctx->as_nr); @@ -1683,8 +1883,8 @@ int kbase_gpu_munmap(struct kbase_context *kctx, struct kbase_va_region *reg) /* The allocation could still have active mappings. */ if (user_buf->current_mapping_usage_count == 0) { kbase_jd_user_buf_unmap(kctx, reg->gpu_alloc, - (reg->flags & (KBASE_REG_CPU_WR | - KBASE_REG_GPU_WR))); + (reg->flags & (KBASE_REG_CPU_WR | + KBASE_REG_GPU_WR))); } } } @@ -2018,22 +2218,35 @@ int kbase_mem_free_region(struct kbase_context *kctx, struct kbase_va_region *re goto out; } +#if MALI_USE_CSF + if (((reg->flags & KBASE_REG_ZONE_MASK) == KBASE_REG_ZONE_FIXED_VA) || + ((reg->flags & KBASE_REG_ZONE_MASK) == KBASE_REG_ZONE_EXEC_FIXED_VA)) { + if (reg->flags & KBASE_REG_FIXED_ADDRESS) + atomic64_dec(&kctx->num_fixed_allocs); + else + atomic64_dec(&kctx->num_fixable_allocs); + } +#endif + /* This will also free the physical pages */ kbase_free_alloced_region(reg); - out: +out: return err; } KBASE_EXPORT_TEST_API(kbase_mem_free_region); /** - * Free the region from the GPU and unregister it. + * kbase_mem_free - Free the region from the GPU and unregister it. + * * @kctx: KBase context * @gpu_addr: GPU address to free * * This function implements the free operation on a memory segment. * It will loudly fail if called with outstanding mappings. + * + * Return: 0 on success. */ int kbase_mem_free(struct kbase_context *kctx, u64 gpu_addr) { @@ -2045,12 +2258,14 @@ int kbase_mem_free(struct kbase_context *kctx, u64 gpu_addr) __func__, gpu_addr, (void *)kctx); if ((gpu_addr & ~PAGE_MASK) && (gpu_addr >= PAGE_SIZE)) { - dev_warn(kctx->kbdev->dev, "kbase_mem_free: gpu_addr parameter is invalid"); + dev_warn(kctx->kbdev->dev, "%s: gpu_addr parameter is invalid", __func__); return -EINVAL; } if (gpu_addr == 0) { - dev_warn(kctx->kbdev->dev, "gpu_addr 0 is reserved for the ringbuffer and it's an error to try to free it using kbase_mem_free\n"); + dev_warn(kctx->kbdev->dev, + "gpu_addr 0 is reserved for the ringbuffer and it's an error to try to free it using %s\n", + __func__); return -EINVAL; } kbase_gpu_vm_lock(kctx); @@ -2076,8 +2291,8 @@ int kbase_mem_free(struct kbase_context *kctx, u64 gpu_addr) /* Validate the region */ reg = kbase_region_tracker_find_region_base_address(kctx, gpu_addr); if (kbase_is_region_invalid_or_free(reg)) { - dev_warn(kctx->kbdev->dev, "kbase_mem_free called with nonexistent gpu_addr 0x%llX", - gpu_addr); + dev_warn(kctx->kbdev->dev, "%s called with nonexistent gpu_addr 0x%llX", + __func__, gpu_addr); err = -EINVAL; goto out_unlock; } @@ -2092,7 +2307,7 @@ int kbase_mem_free(struct kbase_context *kctx, u64 gpu_addr) err = kbase_mem_free_region(kctx, reg); } - out_unlock: +out_unlock: kbase_gpu_vm_unlock(kctx); return err; } @@ -2198,6 +2413,11 @@ int kbase_update_region_flags(struct kbase_context *kctx, if (flags & BASE_MEM_GPU_VA_SAME_4GB_PAGE) reg->flags |= KBASE_REG_GPU_VA_SAME_4GB_PAGE; +#if MALI_USE_CSF + if (flags & BASE_MEM_FIXED) + reg->flags |= KBASE_REG_FIXED_ADDRESS; +#endif + return 0; } @@ -3049,6 +3269,14 @@ bool kbase_check_alloc_flags(unsigned long flags) (BASE_MEM_COHERENT_LOCAL | BASE_MEM_COHERENT_SYSTEM)) return false; +#if MALI_USE_CSF + if ((flags & BASE_MEM_SAME_VA) && (flags & (BASE_MEM_FIXABLE | BASE_MEM_FIXED))) + return false; + + if ((flags & BASE_MEM_FIXABLE) && (flags & BASE_MEM_FIXED)) + return false; +#endif + return true; } @@ -3070,7 +3298,11 @@ bool kbase_check_import_flags(unsigned long flags) if (flags & BASE_MEM_GROW_ON_GPF) return false; -#if !MALI_USE_CSF +#if MALI_USE_CSF + /* Imported memory cannot be fixed */ + if ((flags & (BASE_MEM_FIXED | BASE_MEM_FIXABLE))) + return false; +#else /* Imported memory cannot be aligned to the end of its initial commit */ if (flags & BASE_MEM_TILER_ALIGN_TOP) return false; @@ -3231,7 +3463,7 @@ KBASE_EXPORT_TEST_API(kbase_gpu_vm_unlock); #if IS_ENABLED(CONFIG_DEBUG_FS) struct kbase_jit_debugfs_data { - int (*func)(struct kbase_jit_debugfs_data *); + int (*func)(struct kbase_jit_debugfs_data *data); struct mutex lock; struct kbase_context *kctx; u64 active_value; @@ -3454,8 +3686,8 @@ KBASE_JIT_DEBUGFS_DECLARE(kbase_jit_debugfs_trim_fops, void kbase_jit_debugfs_init(struct kbase_context *kctx) { /* prevent unprivileged use of debug file system - * in old kernel version - */ + * in old kernel version + */ #if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) /* only for newer kernel version debug file system is safe */ const mode_t mode = 0444; @@ -4238,9 +4470,8 @@ struct kbase_va_region *kbase_jit_allocate(struct kbase_context *kctx, mutex_unlock(&kctx->jit_evict_lock); kbase_gpu_vm_unlock(kctx); - reg = kbase_mem_alloc(kctx, info->va_pages, info->commit_pages, - info->extension, &flags, &gpu_addr, - mmu_sync_info); + reg = kbase_mem_alloc(kctx, info->va_pages, info->commit_pages, info->extension, + &flags, &gpu_addr, mmu_sync_info); if (!reg) { /* Most likely not enough GPU virtual space left for * the new JIT allocation. @@ -4580,34 +4811,25 @@ int kbase_jd_user_buf_pin_pages(struct kbase_context *kctx, write = reg->flags & (KBASE_REG_CPU_WR | KBASE_REG_GPU_WR); #if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages( - NULL, mm, address, - alloc->imported.user_buf.nr_pages, + pinned_pages = get_user_pages(NULL, mm, address, alloc->imported.user_buf.nr_pages, #if KERNEL_VERSION(4, 4, 168) <= LINUX_VERSION_CODE && \ KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE - write ? FOLL_WRITE : 0, pages, NULL); + write ? FOLL_WRITE : 0, pages, NULL); #else - write, 0, pages, NULL); + write, 0, pages, NULL); #endif #elif KERNEL_VERSION(4, 9, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages_remote( - NULL, mm, - address, alloc->imported.user_buf.nr_pages, - write, 0, pages, NULL); + pinned_pages = get_user_pages_remote(NULL, mm, address, alloc->imported.user_buf.nr_pages, + write, 0, pages, NULL); #elif KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages_remote( - NULL, mm, - address, alloc->imported.user_buf.nr_pages, - write ? FOLL_WRITE : 0, pages, NULL); + pinned_pages = get_user_pages_remote(NULL, mm, address, alloc->imported.user_buf.nr_pages, + write ? FOLL_WRITE : 0, pages, NULL); #elif KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages_remote( - NULL, mm, - address, alloc->imported.user_buf.nr_pages, - write ? FOLL_WRITE : 0, pages, NULL, NULL); + pinned_pages = get_user_pages_remote(NULL, mm, address, alloc->imported.user_buf.nr_pages, + write ? FOLL_WRITE : 0, pages, NULL, NULL); #else - pinned_pages = pin_user_pages_remote( - mm, address, alloc->imported.user_buf.nr_pages, - write ? FOLL_WRITE : 0, pages, NULL, NULL); + pinned_pages = pin_user_pages_remote(mm, address, alloc->imported.user_buf.nr_pages, + write ? FOLL_WRITE : 0, pages, NULL, NULL); #endif if (pinned_pages <= 0) @@ -4664,7 +4886,8 @@ static int kbase_jd_user_buf_map(struct kbase_context *kctx, dma_addr = dma_map_page(dev, pages[i], offset, min, DMA_BIDIRECTIONAL); - if (dma_mapping_error(dev, dma_addr)) + err = dma_mapping_error(dev, dma_addr); + if (err) goto unwind; alloc->imported.user_buf.dma_addrs[i] = dma_addr; |