summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/vidmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/vidmem.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/vidmem.c43
1 files changed, 20 insertions, 23 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/vidmem.c b/drivers/gpu/nvgpu/common/linux/vidmem.c
index ea8e552f..92e7e504 100644
--- a/drivers/gpu/nvgpu/common/linux/vidmem.c
+++ b/drivers/gpu/nvgpu/common/linux/vidmem.c
@@ -84,6 +84,8 @@ static void gk20a_vidbuf_release(struct dma_buf *dmabuf)
84 84
85 nvgpu_kfree(g, linux_buf); 85 nvgpu_kfree(g, linux_buf);
86 nvgpu_vidmem_buf_free(g, buf); 86 nvgpu_vidmem_buf_free(g, buf);
87
88 gk20a_put(g);
87} 89}
88 90
89static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num) 91static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num)
@@ -160,13 +162,21 @@ struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf)
160 162
161int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes) 163int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes)
162{ 164{
163 struct nvgpu_vidmem_buf *buf; 165 struct nvgpu_vidmem_buf *buf = NULL;
164 struct nvgpu_vidmem_linux *priv; 166 struct nvgpu_vidmem_linux *priv;
165 int err, fd; 167 int err, fd;
166 168
169 /*
170 * This ref is released when the dma_buf is closed.
171 */
172 if (!gk20a_get(g))
173 return -ENODEV;
174
167 priv = nvgpu_kzalloc(g, sizeof(*priv)); 175 priv = nvgpu_kzalloc(g, sizeof(*priv));
168 if (!priv) 176 if (!priv) {
169 return -ENOMEM; 177 err = -ENOMEM;
178 goto fail;
179 }
170 180
171 buf = nvgpu_vidmem_user_alloc(g, bytes); 181 buf = nvgpu_vidmem_user_alloc(g, bytes);
172 if (!buf) { 182 if (!buf) {
@@ -195,8 +205,10 @@ int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes)
195 return fd; 205 return fd;
196 206
197fail: 207fail:
198 nvgpu_kfree(g, priv);
199 nvgpu_vidmem_buf_free(g, buf); 208 nvgpu_vidmem_buf_free(g, buf);
209 nvgpu_kfree(g, priv);
210 gk20a_put(g);
211
200 return err; 212 return err;
201} 213}
202 214
@@ -229,24 +241,9 @@ int nvgpu_vidmem_buf_access_memory(struct gk20a *g, struct dma_buf *dmabuf,
229 return err; 241 return err;
230} 242}
231 243
232void nvgpu_vidmem_clear_mem_worker(struct work_struct *work) 244void __nvgpu_mem_free_vidmem_alloc(struct gk20a *g, struct nvgpu_mem *vidmem)
233{ 245{
234 struct mm_gk20a *mm = container_of(work, struct mm_gk20a, 246 nvgpu_free(vidmem->allocator,
235 vidmem.clear_mem_worker); 247 (u64)nvgpu_vidmem_get_page_alloc(vidmem->priv.sgt->sgl));
236 struct gk20a *g = mm->g; 248 nvgpu_free_sgtable(g, &vidmem->priv.sgt);
237 struct nvgpu_mem *mem;
238
239 while ((mem = nvgpu_vidmem_get_pending_alloc(mm)) != NULL) {
240 nvgpu_vidmem_clear(g, mem);
241 nvgpu_free(mem->allocator,
242 (u64)nvgpu_vidmem_get_page_alloc(mem->priv.sgt->sgl));
243 nvgpu_free_sgtable(g, &mem->priv.sgt);
244
245 WARN_ON(nvgpu_atomic64_sub_return(mem->aligned_size,
246 &g->mm.vidmem.bytes_pending) < 0);
247 mem->size = 0;
248 mem->aperture = APERTURE_INVALID;
249
250 nvgpu_kfree(g, mem);
251 }
252} 249}