summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2016-11-29 19:01:41 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-02-07 17:54:02 -0500
commit7e403974d3584ab8880e42d422ee3afb7f49d6f3 (patch)
tree9103e53336d8ec70f81acab5d39c9da2107abd2e /drivers
parent07f07981733135f648c53acfedf03b43045fed08 (diff)
gpu: nvgpu: Simplify ref-counting on VMs
Simplify ref-counting on VMs: take a ref when a VM is bound to a channel and drop a ref when a channel is freed. Previously ref-counts were scattered over the driver. Also the CE and CDE code would bind channels with custom rolled code. This was because the gk20a_vm_bind_channel() function took an as_share as the VM argument (the VM was then inferred from that as_share). However, it is trivial to abtract that bit out and allow a central bind channel function that just takes a VM and a channel. Bug 1846718 Change-Id: I156aab259f6c7a2fa338408c6c4a3a464cd44a0c Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1261886 Reviewed-by: Richard Zhao <rizhao@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/cde_gk20a.c4
-rw-r--r--drivers/gpu/nvgpu/gk20a/ce2_gk20a.c4
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c18
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c21
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/vgpu/mm_vgpu.c3
6 files changed, 22 insertions, 29 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
index 7b81f5e8..384fbdef 100644
--- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
@@ -1203,9 +1203,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
1203 } 1203 }
1204 1204
1205 /* bind the channel to the vm */ 1205 /* bind the channel to the vm */
1206 gk20a_vm_get(&g->mm.cde.vm); 1206 err = __gk20a_vm_bind_channel(&g->mm.cde.vm, ch);
1207 ch->vm = &g->mm.cde.vm;
1208 err = channel_gk20a_commit_va(ch);
1209 if (err) { 1207 if (err) {
1210 gk20a_warn(cde_ctx->dev, "cde: could not bind vm"); 1208 gk20a_warn(cde_ctx->dev, "cde: could not bind vm");
1211 goto err_commit_va; 1209 goto err_commit_va;
diff --git a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
index af49c864..7afed41f 100644
--- a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
@@ -453,9 +453,7 @@ u32 gk20a_ce_create_context_with_cb(struct device *dev,
453 } 453 }
454 454
455 /* bind the channel to the vm */ 455 /* bind the channel to the vm */
456 gk20a_vm_get(&g->mm.ce.vm); 456 err = __gk20a_vm_bind_channel(&g->mm.ce.vm, ce_ctx->ch);
457 ce_ctx->vm = ce_ctx->ch->vm = &g->mm.ce.vm;
458 err = channel_gk20a_commit_va(ce_ctx->ch);
459 if (err) { 457 if (err) {
460 gk20a_err(ce_ctx->dev, "ce: could not bind vm"); 458 gk20a_err(ce_ctx->dev, "ce: could not bind vm");
461 goto end; 459 goto end;
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index e272b130..c8b1c105 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -1008,11 +1008,10 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
1008 if (ch->hw_sema) 1008 if (ch->hw_sema)
1009 gk20a_semaphore_free_hw_sema(ch); 1009 gk20a_semaphore_free_hw_sema(ch);
1010 1010
1011 /* release channel binding to the as_share */ 1011 /*
1012 if (ch_vm->as_share) 1012 * When releasing the channel we unbind the VM - so release the ref.
1013 gk20a_as_release_share(ch_vm->as_share); 1013 */
1014 else 1014 gk20a_vm_put(ch_vm);
1015 gk20a_vm_put(ch_vm);
1016 1015
1017 spin_lock(&ch->update_fn_lock); 1016 spin_lock(&ch->update_fn_lock);
1018 ch->update_fn = NULL; 1017 ch->update_fn = NULL;
@@ -2252,14 +2251,11 @@ static int gk20a_channel_add_job(struct channel_gk20a *c,
2252 int err = 0, num_mapped_buffers = 0; 2251 int err = 0, num_mapped_buffers = 0;
2253 bool pre_alloc_enabled = channel_gk20a_is_prealloc_enabled(c); 2252 bool pre_alloc_enabled = channel_gk20a_is_prealloc_enabled(c);
2254 2253
2255 /* job needs reference to this vm (released in channel_update) */
2256 gk20a_vm_get(vm);
2257
2258 if (!skip_buffer_refcounting) { 2254 if (!skip_buffer_refcounting) {
2259 err = gk20a_vm_get_buffers(vm, &mapped_buffers, 2255 err = gk20a_vm_get_buffers(vm, &mapped_buffers,
2260 &num_mapped_buffers); 2256 &num_mapped_buffers);
2261 if (err) 2257 if (err)
2262 goto err_put_vm; 2258 return err;
2263 } 2259 }
2264 2260
2265 /* put() is done in gk20a_channel_update() when the job is done */ 2261 /* put() is done in gk20a_channel_update() when the job is done */
@@ -2293,8 +2289,6 @@ static int gk20a_channel_add_job(struct channel_gk20a *c,
2293 2289
2294err_put_buffers: 2290err_put_buffers:
2295 gk20a_vm_put_buffers(vm, mapped_buffers, num_mapped_buffers); 2291 gk20a_vm_put_buffers(vm, mapped_buffers, num_mapped_buffers);
2296err_put_vm:
2297 gk20a_vm_put(vm);
2298 2292
2299 return err; 2293 return err;
2300} 2294}
@@ -2385,8 +2379,6 @@ static void gk20a_channel_clean_up_jobs(struct channel_gk20a *c,
2385 gk20a_free_priv_cmdbuf(c, job->wait_cmd); 2379 gk20a_free_priv_cmdbuf(c, job->wait_cmd);
2386 gk20a_free_priv_cmdbuf(c, job->incr_cmd); 2380 gk20a_free_priv_cmdbuf(c, job->incr_cmd);
2387 2381
2388 /* job is done. release its vm reference (taken in add_job) */
2389 gk20a_vm_put(vm);
2390 /* another bookkeeping taken in add_job. caller must hold a ref 2382 /* another bookkeeping taken in add_job. caller must hold a ref
2391 * so this wouldn't get freed here. */ 2383 * so this wouldn't get freed here. */
2392 gk20a_channel_put(c); 2384 gk20a_channel_put(c);
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index e589e312..ea5ea73f 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -4199,10 +4199,8 @@ static int gk20a_init_sema_pool(struct vm_gk20a *vm)
4199 return -ENOMEM; 4199 return -ENOMEM;
4200 4200
4201 vm->sema_pool = gk20a_semaphore_pool_alloc(sema_sea); 4201 vm->sema_pool = gk20a_semaphore_pool_alloc(sema_sea);
4202 if (!vm->sema_pool) { 4202 if (!vm->sema_pool)
4203 gk20a_vm_put(vm);
4204 return -ENOMEM; 4203 return -ENOMEM;
4205 }
4206 4204
4207 /* 4205 /*
4208 * Allocate a chunk of GPU VA space for mapping the semaphores. We will 4206 * Allocate a chunk of GPU VA space for mapping the semaphores. We will
@@ -4227,7 +4225,7 @@ static int gk20a_init_sema_pool(struct vm_gk20a *vm)
4227 gk20a_semaphore_pool_unmap(vm->sema_pool, vm); 4225 gk20a_semaphore_pool_unmap(vm->sema_pool, vm);
4228 nvgpu_free(vm->vma[gmmu_page_size_small], 4226 nvgpu_free(vm->vma[gmmu_page_size_small],
4229 vm->sema_pool->gpu_va); 4227 vm->sema_pool->gpu_va);
4230 gk20a_vm_put(vm); 4228 return err;
4231 } 4229 }
4232 4230
4233 return 0; 4231 return 0;
@@ -4632,12 +4630,10 @@ int gk20a_vm_release_share(struct gk20a_as_share *as_share)
4632 gk20a_dbg_fn(""); 4630 gk20a_dbg_fn("");
4633 4631
4634 vm->as_share = NULL; 4632 vm->as_share = NULL;
4633 as_share->vm = NULL;
4635 4634
4636 /* put as reference to vm */
4637 gk20a_vm_put(vm); 4635 gk20a_vm_put(vm);
4638 4636
4639 as_share->vm = NULL;
4640
4641 return 0; 4637 return 0;
4642} 4638}
4643 4639
@@ -4792,14 +4788,13 @@ int gk20a_vm_free_space(struct gk20a_as_share *as_share,
4792 return err; 4788 return err;
4793} 4789}
4794 4790
4795int gk20a_vm_bind_channel(struct gk20a_as_share *as_share, 4791int __gk20a_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch)
4796 struct channel_gk20a *ch)
4797{ 4792{
4798 int err = 0; 4793 int err = 0;
4799 struct vm_gk20a *vm = as_share->vm;
4800 4794
4801 gk20a_dbg_fn(""); 4795 gk20a_dbg_fn("");
4802 4796
4797 gk20a_vm_get(vm);
4803 ch->vm = vm; 4798 ch->vm = vm;
4804 err = channel_gk20a_commit_va(ch); 4799 err = channel_gk20a_commit_va(ch);
4805 if (err) 4800 if (err)
@@ -4808,6 +4803,12 @@ int gk20a_vm_bind_channel(struct gk20a_as_share *as_share,
4808 return err; 4803 return err;
4809} 4804}
4810 4805
4806int gk20a_vm_bind_channel(struct gk20a_as_share *as_share,
4807 struct channel_gk20a *ch)
4808{
4809 return __gk20a_vm_bind_channel(as_share->vm, ch);
4810}
4811
4811int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) 4812int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev)
4812{ 4813{
4813 struct gk20a_dmabuf_priv *priv; 4814 struct gk20a_dmabuf_priv *priv;
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index 665aea42..f3dffa46 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -707,6 +707,7 @@ int gk20a_vm_free_space(struct gk20a_as_share *as_share,
707 struct nvgpu_as_free_space_args *args); 707 struct nvgpu_as_free_space_args *args);
708int gk20a_vm_bind_channel(struct gk20a_as_share *as_share, 708int gk20a_vm_bind_channel(struct gk20a_as_share *as_share,
709 struct channel_gk20a *ch); 709 struct channel_gk20a *ch);
710int __gk20a_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch);
710 711
711/* batching eliminates redundant cache flushes and invalidates */ 712/* batching eliminates redundant cache flushes and invalidates */
712void gk20a_vm_mapping_batch_start(struct vm_gk20a_mapping_batch *batch); 713void gk20a_vm_mapping_batch_start(struct vm_gk20a_mapping_batch *batch);
diff --git a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
index 76631b96..f97acd47 100644
--- a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
@@ -446,6 +446,9 @@ static int vgpu_vm_bind_channel(struct gk20a_as_share *as_share,
446 err = -ENOMEM; 446 err = -ENOMEM;
447 } 447 }
448 448
449 if (ch->vm)
450 gk20a_vm_get(ch->vm);
451
449 return err; 452 return err;
450} 453}
451 454