diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-08-18 05:00:11 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2016-09-01 12:10:54 -0400 |
commit | 9ebd051779827a05d62fbba7ffa65cf401c256b3 (patch) | |
tree | 393ca0feab2fb2790005d44c079ec7257df9cb2e /drivers/gpu/nvgpu/gk20a | |
parent | 50fec50bffea22dc6c19c86da6ecb604c940c424 (diff) |
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 <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1203099
(cherry picked from commit 8f0b0122f36a0b6f1932fa9a98d7eb03b1f623d1)
Reviewed-on: http://git-master/r/1210953
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 31 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 2 |
2 files changed, 24 insertions, 9 deletions
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) | |||
2124 | if (!buf->mem) | 2124 | if (!buf->mem) |
2125 | goto err_kfree; | 2125 | goto err_kfree; |
2126 | 2126 | ||
2127 | buf->mem->user_mem = true; | ||
2128 | |||
2127 | err = gk20a_gmmu_alloc_vid(g, bytes, buf->mem); | 2129 | err = gk20a_gmmu_alloc_vid(g, bytes, buf->mem); |
2128 | if (err) | 2130 | if (err) |
2129 | goto err_memfree; | 2131 | goto err_memfree; |
@@ -2962,6 +2964,7 @@ int gk20a_gmmu_alloc_attr_vid_at(struct gk20a *g, enum dma_attr attr, | |||
2962 | 2964 | ||
2963 | mem->size = size; | 2965 | mem->size = size; |
2964 | mem->aperture = APERTURE_VIDMEM; | 2966 | mem->aperture = APERTURE_VIDMEM; |
2967 | mem->allocator = vidmem_alloc; | ||
2965 | 2968 | ||
2966 | INIT_LIST_HEAD(&mem->clear_list_entry); | 2969 | INIT_LIST_HEAD(&mem->clear_list_entry); |
2967 | 2970 | ||
@@ -2985,15 +2988,25 @@ static void gk20a_gmmu_free_attr_vid(struct gk20a *g, enum dma_attr attr, | |||
2985 | #if defined(CONFIG_GK20A_VIDMEM) | 2988 | #if defined(CONFIG_GK20A_VIDMEM) |
2986 | bool was_empty; | 2989 | bool was_empty; |
2987 | 2990 | ||
2988 | mutex_lock(&g->mm.vidmem.clear_list_mutex); | 2991 | if (mem->user_mem) { |
2989 | was_empty = list_empty(&g->mm.vidmem.clear_list_head); | 2992 | mutex_lock(&g->mm.vidmem.clear_list_mutex); |
2990 | list_add_tail(&mem->clear_list_entry, | 2993 | was_empty = list_empty(&g->mm.vidmem.clear_list_head); |
2991 | &g->mm.vidmem.clear_list_head); | 2994 | list_add_tail(&mem->clear_list_entry, |
2992 | mutex_unlock(&g->mm.vidmem.clear_list_mutex); | 2995 | &g->mm.vidmem.clear_list_head); |
2996 | mutex_unlock(&g->mm.vidmem.clear_list_mutex); | ||
2997 | |||
2998 | if (was_empty) { | ||
2999 | cancel_work_sync(&g->mm.vidmem_clear_mem_worker); | ||
3000 | schedule_work(&g->mm.vidmem_clear_mem_worker); | ||
3001 | } | ||
3002 | } else { | ||
3003 | /* TODO: clear with PRAMIN here */ | ||
3004 | gk20a_free(mem->allocator, | ||
3005 | sg_dma_address(mem->sgt->sgl)); | ||
3006 | gk20a_free_sgtable(&mem->sgt); | ||
2993 | 3007 | ||
2994 | if (was_empty) { | 3008 | mem->size = 0; |
2995 | cancel_work_sync(&g->mm.vidmem_clear_mem_worker); | 3009 | mem->aperture = APERTURE_INVALID; |
2996 | schedule_work(&g->mm.vidmem_clear_mem_worker); | ||
2997 | } | 3010 | } |
2998 | #endif | 3011 | #endif |
2999 | } | 3012 | } |
@@ -3040,7 +3053,7 @@ static void gk20a_vidmem_clear_mem_worker(struct work_struct *work) | |||
3040 | 3053 | ||
3041 | while ((mem = get_pending_mem_desc(mm)) != NULL) { | 3054 | while ((mem = get_pending_mem_desc(mm)) != NULL) { |
3042 | gk20a_gmmu_clear_vidmem_mem(g, mem); | 3055 | gk20a_gmmu_clear_vidmem_mem(g, mem); |
3043 | gk20a_free(&g->mm.vidmem.allocator, | 3056 | gk20a_free(mem->allocator, |
3044 | sg_dma_address(mem->sgt->sgl)); | 3057 | sg_dma_address(mem->sgt->sgl)); |
3045 | gk20a_free_sgtable(&mem->sgt); | 3058 | gk20a_free_sgtable(&mem->sgt); |
3046 | 3059 | ||
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 { | |||
71 | size_t size; | 71 | size_t size; |
72 | u64 gpu_va; | 72 | u64 gpu_va; |
73 | bool fixed; /* vidmem only */ | 73 | bool fixed; /* vidmem only */ |
74 | bool user_mem; /* vidmem only */ | ||
75 | struct gk20a_allocator *allocator; /* vidmem only */ | ||
74 | struct list_head clear_list_entry; /* vidmem only */ | 76 | struct list_head clear_list_entry; /* vidmem only */ |
75 | }; | 77 | }; |
76 | 78 | ||