From 9ebd051779827a05d62fbba7ffa65cf401c256b3 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Thu, 18 Aug 2016 14:30:11 +0530 Subject: gpu: nvgpu: track allocator and user for each mem Store allocator pointer for each mem_desc This pointer should be used while freeing the mem instead of assuming a common allocator Add flag user_mem to mem_desc which will be set only in case of User vidmem allocations We will delay free of mem in worker only if this flag is set on mem. Otherwise, we will free it immediately This is needed so that all kernel allocations can work with both sysmem and vidmem Jira DNVGPU-84 Change-Id: Ib9a9209b164bc56b7880448f86bd6d42b324cc86 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/1203099 (cherry picked from commit 8f0b0122f36a0b6f1932fa9a98d7eb03b1f623d1) Reviewed-on: http://git-master/r/1210953 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 31 ++++++++++++++++++++++--------- drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 2 ++ 2 files changed, 24 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index c9681861..89390c30 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -2124,6 +2124,8 @@ int gk20a_vidmem_buf_alloc(struct gk20a *g, size_t bytes) if (!buf->mem) goto err_kfree; + buf->mem->user_mem = true; + err = gk20a_gmmu_alloc_vid(g, bytes, buf->mem); if (err) goto err_memfree; @@ -2962,6 +2964,7 @@ int gk20a_gmmu_alloc_attr_vid_at(struct gk20a *g, enum dma_attr attr, mem->size = size; mem->aperture = APERTURE_VIDMEM; + mem->allocator = vidmem_alloc; INIT_LIST_HEAD(&mem->clear_list_entry); @@ -2985,15 +2988,25 @@ static void gk20a_gmmu_free_attr_vid(struct gk20a *g, enum dma_attr attr, #if defined(CONFIG_GK20A_VIDMEM) bool was_empty; - mutex_lock(&g->mm.vidmem.clear_list_mutex); - was_empty = list_empty(&g->mm.vidmem.clear_list_head); - list_add_tail(&mem->clear_list_entry, - &g->mm.vidmem.clear_list_head); - mutex_unlock(&g->mm.vidmem.clear_list_mutex); + if (mem->user_mem) { + mutex_lock(&g->mm.vidmem.clear_list_mutex); + was_empty = list_empty(&g->mm.vidmem.clear_list_head); + list_add_tail(&mem->clear_list_entry, + &g->mm.vidmem.clear_list_head); + mutex_unlock(&g->mm.vidmem.clear_list_mutex); + + if (was_empty) { + cancel_work_sync(&g->mm.vidmem_clear_mem_worker); + schedule_work(&g->mm.vidmem_clear_mem_worker); + } + } else { + /* TODO: clear with PRAMIN here */ + gk20a_free(mem->allocator, + sg_dma_address(mem->sgt->sgl)); + gk20a_free_sgtable(&mem->sgt); - if (was_empty) { - cancel_work_sync(&g->mm.vidmem_clear_mem_worker); - schedule_work(&g->mm.vidmem_clear_mem_worker); + mem->size = 0; + mem->aperture = APERTURE_INVALID; } #endif } @@ -3040,7 +3053,7 @@ static void gk20a_vidmem_clear_mem_worker(struct work_struct *work) while ((mem = get_pending_mem_desc(mm)) != NULL) { gk20a_gmmu_clear_vidmem_mem(g, mem); - gk20a_free(&g->mm.vidmem.allocator, + gk20a_free(mem->allocator, sg_dma_address(mem->sgt->sgl)); gk20a_free_sgtable(&mem->sgt); diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 54d3dfd0..32f8ce39 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h @@ -71,6 +71,8 @@ struct mem_desc { size_t size; u64 gpu_va; bool fixed; /* vidmem only */ + bool user_mem; /* vidmem only */ + struct gk20a_allocator *allocator; /* vidmem only */ struct list_head clear_list_entry; /* vidmem only */ }; -- cgit v1.2.2