diff options
author | Jörg Wagner <jorwag@google.com> | 2022-12-15 14:01:25 +0000 |
---|---|---|
committer | Jörg Wagner <jorwag@google.com> | 2022-12-15 16:27:59 +0000 |
commit | 9ff5b6f2510d94765def3cf7c1fda01e387cabab (patch) | |
tree | d455bcd53cca74df918b3dd0092e806fb29e1461 /mali_kbase/mali_kbase_mem.c | |
parent | c30533582604fe0365bc3ce4e9e8e19dec3109da (diff) | |
download | gpu-9ff5b6f2510d94765def3cf7c1fda01e387cabab.tar.gz |
Mali Valhall Android DDK r40p0-01eac0 KMD
Provenance: 056ded72d351d1bf6319f7b2b925496dd6ad304f (ipdelivery/EAC/v_r40p0)
VX504X08X-BU-00000-r40p0-01eac0 - Valhall Android DDK
VX504X08X-BU-60000-r40p0-01eac0 - Valhall Android Document Bundle
VX504X08X-DC-11001-r40p0-01eac0 - Valhall Android DDK Software Errata
VX504X08X-SW-99006-r40p0-01eac0 - Valhall Android Renderscript AOSP parts
Change-Id: I6db6b45c73c5447dd246533246e65b5ef2c8872f
Diffstat (limited to 'mali_kbase/mali_kbase_mem.c')
-rw-r--r-- | mali_kbase/mali_kbase_mem.c | 112 |
1 files changed, 72 insertions, 40 deletions
diff --git a/mali_kbase/mali_kbase_mem.c b/mali_kbase/mali_kbase_mem.c index e83aec4..3743b4d 100644 --- a/mali_kbase/mali_kbase_mem.c +++ b/mali_kbase/mali_kbase_mem.c @@ -44,6 +44,8 @@ #include <mali_kbase_config_defaults.h> #include <mali_kbase_trace_gpu_mem.h> +#if MALI_JIT_PRESSURE_LIMIT_BASE + /* * Alignment of objects allocated by the GPU inside a just-in-time memory * region whose size is given by an end address @@ -66,6 +68,7 @@ */ #define KBASE_GPU_ALLOCATED_OBJECT_MAX_BYTES (512u) +#endif /* MALI_JIT_PRESSURE_LIMIT_BASE */ /* Forward declarations */ static void free_partial_locked(struct kbase_context *kctx, @@ -429,15 +432,15 @@ void kbase_remove_va_region(struct kbase_device *kbdev, next->nr_pages += reg->nr_pages; rb_erase(&(reg->rblink), reg_rbtree); merged_back = 1; - if (merged_front) { - /* We already merged with prev, free it */ - kfree(reg); - } } } - /* If we failed to merge then we need to add a new block */ - if (!(merged_front || merged_back)) { + if (merged_front && merged_back) { + /* We already merged with prev, free it */ + kfree(reg); + } else if (!(merged_front || merged_back)) { + /* If we failed to merge then we need to add a new block */ + /* * We didn't merge anything. Try to add a new free * placeholder, and in any case, remove the original one. @@ -1416,6 +1419,7 @@ int kbase_mem_init(struct kbase_device *kbdev) memdev = &kbdev->memdev; + kbase_mem_migrate_init(kbdev); kbase_mem_pool_group_config_set_max_size(&kbdev->mem_pool_defaults, KBASE_MEM_POOL_MAX_SIZE_KCTX); @@ -1478,8 +1482,7 @@ int kbase_mem_init(struct kbase_device *kbdev) kbase_mem_pool_group_config_set_max_size(&mem_pool_defaults, KBASE_MEM_POOL_MAX_SIZE_KBDEV); - err = kbase_mem_pool_group_init(&kbdev->mem_pools, kbdev, - &mem_pool_defaults, NULL); + err = kbase_mem_pool_group_init(&kbdev->mem_pools, kbdev, &mem_pool_defaults, NULL); } return err; @@ -1505,6 +1508,8 @@ void kbase_mem_term(struct kbase_device *kbdev) kbase_mem_pool_group_term(&kbdev->mem_pools); + kbase_mem_migrate_term(kbdev); + WARN_ON(kbdev->total_gpu_pages); WARN_ON(!RB_EMPTY_ROOT(&kbdev->process_root)); WARN_ON(!RB_EMPTY_ROOT(&kbdev->dma_buf_root)); @@ -1613,6 +1618,7 @@ static struct kbase_context *kbase_reg_flags_to_kctx( * alloc object will be released. * It is a bug if no alloc object exists for non-free regions. * + * If region is KBASE_REG_ZONE_MCU_SHARED it is freed */ void kbase_free_alloced_region(struct kbase_va_region *reg) { @@ -1636,6 +1642,13 @@ void kbase_free_alloced_region(struct kbase_va_region *reg) (void *)reg); #if MALI_USE_CSF if (reg->flags & KBASE_REG_CSF_EVENT) + /* + * This should not be reachable if called from 'mcu_shared' functions + * such as: + * kbase_csf_firmware_mcu_shared_mapping_init + * kbase_csf_firmware_mcu_shared_mapping_term + */ + kbase_unlink_event_mem_page(kctx, reg); #endif @@ -2004,7 +2017,8 @@ void kbase_sync_single(struct kbase_context *kctx, BUG_ON(!cpu_page); BUG_ON(offset + size > PAGE_SIZE); - dma_addr = kbase_dma_addr(cpu_page) + offset; + dma_addr = kbase_dma_addr_from_tagged(t_cpu_pa) + offset; + if (sync_fn == KBASE_SYNC_TO_CPU) dma_sync_single_for_cpu(kctx->kbdev->dev, dma_addr, size, DMA_BIDIRECTIONAL); @@ -2015,19 +2029,20 @@ void kbase_sync_single(struct kbase_context *kctx, void *src = NULL; void *dst = NULL; struct page *gpu_page; + dma_addr_t dma_addr; if (WARN(!gpu_pa, "No GPU PA found for infinite cache op")) return; gpu_page = pfn_to_page(PFN_DOWN(gpu_pa)); + dma_addr = kbase_dma_addr_from_tagged(t_gpu_pa) + offset; if (sync_fn == KBASE_SYNC_TO_DEVICE) { src = ((unsigned char *)kmap(cpu_page)) + offset; dst = ((unsigned char *)kmap(gpu_page)) + offset; } else if (sync_fn == KBASE_SYNC_TO_CPU) { - dma_sync_single_for_cpu(kctx->kbdev->dev, - kbase_dma_addr(gpu_page) + offset, - size, DMA_BIDIRECTIONAL); + dma_sync_single_for_cpu(kctx->kbdev->dev, dma_addr, size, + DMA_BIDIRECTIONAL); src = ((unsigned char *)kmap(gpu_page)) + offset; dst = ((unsigned char *)kmap(cpu_page)) + offset; } @@ -2035,9 +2050,8 @@ void kbase_sync_single(struct kbase_context *kctx, kunmap(gpu_page); kunmap(cpu_page); if (sync_fn == KBASE_SYNC_TO_DEVICE) - dma_sync_single_for_device(kctx->kbdev->dev, - kbase_dma_addr(gpu_page) + offset, - size, DMA_BIDIRECTIONAL); + dma_sync_single_for_device(kctx->kbdev->dev, dma_addr, size, + DMA_BIDIRECTIONAL); } } @@ -2188,6 +2202,25 @@ int kbase_mem_free_region(struct kbase_context *kctx, struct kbase_va_region *re return -EINVAL; } + /* If a region has been made evictable then we must unmake it + * before trying to free it. + * If the memory hasn't been reclaimed it will be unmapped and freed + * below, if it has been reclaimed then the operations below are no-ops. + */ + if (reg->flags & KBASE_REG_DONT_NEED) { + WARN_ON(reg->cpu_alloc->type != KBASE_MEM_TYPE_NATIVE); + mutex_lock(&kctx->jit_evict_lock); + /* Unlink the physical allocation before unmaking it evictable so + * that the allocation isn't grown back to its last backed size + * as we're going to unmap it anyway. + */ + reg->cpu_alloc->reg = NULL; + if (reg->cpu_alloc != reg->gpu_alloc) + reg->gpu_alloc->reg = NULL; + mutex_unlock(&kctx->jit_evict_lock); + kbase_mem_evictable_unmake(reg->gpu_alloc); + } + err = kbase_gpu_munmap(kctx, reg); if (err) { dev_warn(kctx->kbdev->dev, "Could not unmap from the GPU...\n"); @@ -2443,11 +2476,8 @@ int kbase_alloc_phy_pages_helper(struct kbase_mem_phy_alloc *alloc, if (nr_left >= (SZ_2M / SZ_4K)) { int nr_lp = nr_left / (SZ_2M / SZ_4K); - res = kbase_mem_pool_alloc_pages( - &kctx->mem_pools.large[alloc->group_id], - nr_lp * (SZ_2M / SZ_4K), - tp, - true); + res = kbase_mem_pool_alloc_pages(&kctx->mem_pools.large[alloc->group_id], + nr_lp * (SZ_2M / SZ_4K), tp, true); if (res > 0) { nr_left -= res; @@ -2546,9 +2576,8 @@ no_new_partial: #endif if (nr_left) { - res = kbase_mem_pool_alloc_pages( - &kctx->mem_pools.small[alloc->group_id], - nr_left, tp, false); + res = kbase_mem_pool_alloc_pages(&kctx->mem_pools.small[alloc->group_id], nr_left, + tp, false); if (res <= 0) goto alloc_failed; } @@ -3420,10 +3449,6 @@ int kbase_check_alloc_sizes(struct kbase_context *kctx, unsigned long flags, #undef KBASE_MSG_PRE } -/** - * kbase_gpu_vm_lock() - Acquire the per-context region list lock - * @kctx: KBase context - */ void kbase_gpu_vm_lock(struct kbase_context *kctx) { KBASE_DEBUG_ASSERT(kctx != NULL); @@ -3432,10 +3457,6 @@ void kbase_gpu_vm_lock(struct kbase_context *kctx) KBASE_EXPORT_TEST_API(kbase_gpu_vm_lock); -/** - * kbase_gpu_vm_unlock() - Release the per-context region list lock - * @kctx: KBase context - */ void kbase_gpu_vm_unlock(struct kbase_context *kctx) { KBASE_DEBUG_ASSERT(kctx != NULL); @@ -3760,7 +3781,7 @@ int kbase_jit_init(struct kbase_context *kctx) INIT_WORK(&kctx->jit_work, kbase_jit_destroy_worker); #if MALI_USE_CSF - spin_lock_init(&kctx->csf.kcpu_queues.jit_lock); + mutex_init(&kctx->csf.kcpu_queues.jit_lock); INIT_LIST_HEAD(&kctx->csf.kcpu_queues.jit_cmds_head); INIT_LIST_HEAD(&kctx->csf.kcpu_queues.jit_blocked_queues); #else /* !MALI_USE_CSF */ @@ -4200,7 +4221,9 @@ static bool jit_allow_allocate(struct kbase_context *kctx, { #if !MALI_USE_CSF lockdep_assert_held(&kctx->jctx.lock); -#endif +#else /* MALI_USE_CSF */ + lockdep_assert_held(&kctx->csf.kcpu_queues.jit_lock); +#endif /* !MALI_USE_CSF */ #if MALI_JIT_PRESSURE_LIMIT_BASE if (!ignore_pressure_limit && @@ -4293,7 +4316,9 @@ struct kbase_va_region *kbase_jit_allocate(struct kbase_context *kctx, #if !MALI_USE_CSF lockdep_assert_held(&kctx->jctx.lock); -#endif +#else /* MALI_USE_CSF */ + lockdep_assert_held(&kctx->csf.kcpu_queues.jit_lock); +#endif /* !MALI_USE_CSF */ if (!jit_allow_allocate(kctx, info, ignore_pressure_limit)) return NULL; @@ -4501,6 +4526,12 @@ void kbase_jit_free(struct kbase_context *kctx, struct kbase_va_region *reg) { u64 old_pages; +#if !MALI_USE_CSF + lockdep_assert_held(&kctx->jctx.lock); +#else /* MALI_USE_CSF */ + lockdep_assert_held(&kctx->csf.kcpu_queues.jit_lock); +#endif /* !MALI_USE_CSF */ + /* JIT id not immediately available here, so use 0u */ trace_mali_jit_free(reg, 0u); @@ -4594,6 +4625,7 @@ bool kbase_jit_evict(struct kbase_context *kctx) reg = list_entry(kctx->jit_pool_head.prev, struct kbase_va_region, jit_node); list_del(®->jit_node); + list_del_init(®->gpu_alloc->evict_node); } mutex_unlock(&kctx->jit_evict_lock); @@ -4618,12 +4650,10 @@ void kbase_jit_term(struct kbase_context *kctx) walker = list_first_entry(&kctx->jit_pool_head, struct kbase_va_region, jit_node); list_del(&walker->jit_node); + list_del_init(&walker->gpu_alloc->evict_node); mutex_unlock(&kctx->jit_evict_lock); - /* As context is terminating, directly free the backing pages - * without unmapping them from the GPU as done in - * kbase_region_tracker_erase_rbtree(). - */ - kbase_free_alloced_region(walker); + walker->flags &= ~KBASE_REG_NO_USER_FREE; + kbase_mem_free_region(kctx, walker); mutex_lock(&kctx->jit_evict_lock); } @@ -4632,8 +4662,10 @@ void kbase_jit_term(struct kbase_context *kctx) walker = list_first_entry(&kctx->jit_active_head, struct kbase_va_region, jit_node); list_del(&walker->jit_node); + list_del_init(&walker->gpu_alloc->evict_node); mutex_unlock(&kctx->jit_evict_lock); - kbase_free_alloced_region(walker); + walker->flags &= ~KBASE_REG_NO_USER_FREE; + kbase_mem_free_region(kctx, walker); mutex_lock(&kctx->jit_evict_lock); } #if MALI_JIT_PRESSURE_LIMIT_BASE |