summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/mm
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2017-08-17 19:16:49 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-10-13 18:19:28 -0400
commit59e4089278bd052b440293356605ce524e4944db (patch)
treee9c48f09561f913db919bf8bbd4b39205c7bf606 /drivers/gpu/nvgpu/common/mm
parent88d5f6b4154d6803ecf3b0dee7208f9f1f10a793 (diff)
gpu: nvgpu: Separate vidmem alloc from Linux code
Split the core vidmem allocation from the Linux component of vidmem allocation. The core vidmem allocation allocates the nvgpu_mem struct that defines the vidmem buffer in the core MM code. The Linux code now allocates some Linux specific stuff (dma_buf, etc) and also allocates the core vidmem buf. JIRA NVGPU-30 JIRA NVGPU-138 Change-Id: I88e87e0abd5ec714610eacc6eac17e148bcee3ce Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1540708 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/mm')
-rw-r--r--drivers/gpu/nvgpu/common/mm/vidmem.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/vidmem.c b/drivers/gpu/nvgpu/common/mm/vidmem.c
index c95cedec..18f46c03 100644
--- a/drivers/gpu/nvgpu/common/mm/vidmem.c
+++ b/drivers/gpu/nvgpu/common/mm/vidmem.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/scatterlist.h> 23#include <linux/scatterlist.h>
24 24
25#include <nvgpu/dma.h>
25#include <nvgpu/vidmem.h> 26#include <nvgpu/vidmem.h>
26#include <nvgpu/page_allocator.h> 27#include <nvgpu/page_allocator.h>
27 28
@@ -34,7 +35,7 @@ void nvgpu_vidmem_destroy(struct gk20a *g)
34 nvgpu_alloc_destroy(&g->mm.vidmem.allocator); 35 nvgpu_alloc_destroy(&g->mm.vidmem.allocator);
35} 36}
36 37
37int nvgpu_vidmem_clear_all(struct gk20a *g) 38static int __nvgpu_vidmem_do_clear_all(struct gk20a *g)
38{ 39{
39 struct mm_gk20a *mm = &g->mm; 40 struct mm_gk20a *mm = &g->mm;
40 struct gk20a_fence *gk20a_fence_out = NULL; 41 struct gk20a_fence *gk20a_fence_out = NULL;
@@ -257,3 +258,80 @@ struct nvgpu_mem *nvgpu_vidmem_get_pending_alloc(struct mm_gk20a *mm)
257 258
258 return mem; 259 return mem;
259} 260}
261
262static int nvgpu_vidmem_clear_all(struct gk20a *g)
263{
264 int err;
265
266 if (g->mm.vidmem.cleared)
267 return 0;
268
269 nvgpu_mutex_acquire(&g->mm.vidmem.first_clear_mutex);
270 if (!g->mm.vidmem.cleared) {
271 err = __nvgpu_vidmem_do_clear_all(g);
272 if (err) {
273 nvgpu_mutex_release(&g->mm.vidmem.first_clear_mutex);
274 nvgpu_err(g, "failed to clear whole vidmem");
275 return err;
276 }
277 }
278 nvgpu_mutex_release(&g->mm.vidmem.first_clear_mutex);
279
280 return 0;
281}
282
283struct nvgpu_vidmem_buf *nvgpu_vidmem_user_alloc(struct gk20a *g, size_t bytes)
284{
285 struct nvgpu_vidmem_buf *buf;
286 int err;
287
288 err = nvgpu_vidmem_clear_all(g);
289 if (err)
290 return NULL;
291
292 buf = nvgpu_kzalloc(g, sizeof(*buf));
293 if (!buf)
294 return NULL;
295
296 buf->g = g;
297 buf->mem = nvgpu_kzalloc(g, sizeof(*buf->mem));
298 if (!buf->mem)
299 goto fail;
300
301 err = nvgpu_dma_alloc_vid(g, bytes, buf->mem);
302 if (err)
303 goto fail;
304
305 /*
306 * Alerts the DMA API that when we free this vidmem buf we have to
307 * clear it to avoid leaking data to userspace.
308 */
309 buf->mem->mem_flags |= NVGPU_MEM_FLAG_USER_MEM;
310
311 return buf;
312
313fail:
314 /* buf will never be NULL here. */
315 nvgpu_kfree(g, buf->mem);
316 nvgpu_kfree(g, buf);
317 return NULL;
318}
319
320void nvgpu_vidmem_buf_free(struct gk20a *g, struct nvgpu_vidmem_buf *buf)
321{
322 /*
323 * In some error paths it's convenient to be able to "free" a NULL buf.
324 */
325 if (!buf)
326 return;
327
328 nvgpu_dma_free(g, buf->mem);
329
330 /*
331 * We don't free buf->mem here. This is handled by nvgpu_dma_free()!
332 * Since these buffers are cleared in the background the nvgpu_mem
333 * struct must live on through that. We transfer ownership here to the
334 * DMA API and let the DMA API free the buffer.
335 */
336 nvgpu_kfree(g, buf);
337}