summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2016-04-13 03:54:01 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-04-14 11:42:35 -0400
commitf22df728deb90f1c32318dbeaf011389df8ecb59 (patch)
treee78e8a3939862ea78da0e24ce9193d582cb5c6d6 /drivers
parent289cb4d9bdb7db478397a98f8eb56d60e04a6bfc (diff)
gpu: nvgpu: free global ctx bufs only if allocated
Try to free only allocated buffers in gr_gk20a_free_global_ctx_buffers(), otherwise the destroy function pointer would be NULL and crash for nonallocated buffers. This can happen when init fails for some of the buffers. Additionally, make the pointer NULL when a buffer is destroyed, to signify this state. Also refactor the function upwards and call it from gr_gk20a_alloc_global_ctx_buffers() to reduce code duplication. Change-Id: I6e74795014f5e315b5f8342f544ddfccc0d02b71 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/1126026 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index d085e96f..5317bd87 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -2419,6 +2419,7 @@ static void gk20a_gr_destroy_ctx_buffer(struct gk20a *g,
2419 if (!desc) 2419 if (!desc)
2420 return; 2420 return;
2421 gk20a_gmmu_free_attr(g, DMA_ATTR_NO_KERNEL_MAPPING, &desc->mem); 2421 gk20a_gmmu_free_attr(g, DMA_ATTR_NO_KERNEL_MAPPING, &desc->mem);
2422 desc->destroy = NULL;
2422} 2423}
2423 2424
2424static int gk20a_gr_alloc_ctx_buffer(struct gk20a *g, 2425static int gk20a_gr_alloc_ctx_buffer(struct gk20a *g,
@@ -2437,11 +2438,27 @@ static int gk20a_gr_alloc_ctx_buffer(struct gk20a *g,
2437 return err; 2438 return err;
2438} 2439}
2439 2440
2441static void gr_gk20a_free_global_ctx_buffers(struct gk20a *g)
2442{
2443 struct gr_gk20a *gr = &g->gr;
2444 u32 i;
2445
2446 for (i = 0; i < NR_GLOBAL_CTX_BUF; i++) {
2447 /* destroy exists iff buffer is allocated */
2448 if (gr->global_ctx_buffer[i].destroy) {
2449 gr->global_ctx_buffer[i].destroy(g,
2450 &gr->global_ctx_buffer[i]);
2451 }
2452 }
2453
2454 gk20a_dbg_fn("done");
2455}
2456
2440static int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g) 2457static int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g)
2441{ 2458{
2442 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 2459 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
2443 struct gr_gk20a *gr = &g->gr; 2460 struct gr_gk20a *gr = &g->gr;
2444 int i, attr_buffer_size, err; 2461 int attr_buffer_size, err;
2445 struct device *dev = g->dev; 2462 struct device *dev = g->dev;
2446 2463
2447 u32 cb_buffer_size = gr->bundle_cb_default_size * 2464 u32 cb_buffer_size = gr->bundle_cb_default_size *
@@ -2517,31 +2534,10 @@ static int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g)
2517 2534
2518 clean_up: 2535 clean_up:
2519 gk20a_err(dev_from_gk20a(g), "fail"); 2536 gk20a_err(dev_from_gk20a(g), "fail");
2520 for (i = 0; i < NR_GLOBAL_CTX_BUF; i++) { 2537 gr_gk20a_free_global_ctx_buffers(g);
2521 if (gr->global_ctx_buffer[i].destroy) {
2522 gr->global_ctx_buffer[i].destroy(g,
2523 &gr->global_ctx_buffer[i]);
2524 }
2525 }
2526 return -ENOMEM; 2538 return -ENOMEM;
2527} 2539}
2528 2540
2529static void gr_gk20a_free_global_ctx_buffers(struct gk20a *g)
2530{
2531 struct gr_gk20a *gr = &g->gr;
2532 DEFINE_DMA_ATTRS(attrs);
2533 u32 i;
2534
2535 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
2536
2537 for (i = 0; i < NR_GLOBAL_CTX_BUF; i++) {
2538 gr->global_ctx_buffer[i].destroy(g,
2539 &gr->global_ctx_buffer[i]);
2540 }
2541
2542 gk20a_dbg_fn("done");
2543}
2544
2545static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g, 2541static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2546 struct channel_gk20a *c) 2542 struct channel_gk20a *c)
2547{ 2543{