From 7e403974d3584ab8880e42d422ee3afb7f49d6f3 Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Tue, 29 Nov 2016 16:01:41 -0800 Subject: 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 Reviewed-on: http://git-master/r/1261886 Reviewed-by: Richard Zhao Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 4 +--- drivers/gpu/nvgpu/gk20a/ce2_gk20a.c | 4 +--- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 18 +++++------------- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 21 +++++++++++---------- drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 1 + drivers/gpu/nvgpu/vgpu/mm_vgpu.c | 3 +++ 6 files changed, 22 insertions(+), 29 deletions(-) (limited to 'drivers') 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) } /* bind the channel to the vm */ - gk20a_vm_get(&g->mm.cde.vm); - ch->vm = &g->mm.cde.vm; - err = channel_gk20a_commit_va(ch); + err = __gk20a_vm_bind_channel(&g->mm.cde.vm, ch); if (err) { gk20a_warn(cde_ctx->dev, "cde: could not bind vm"); 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, } /* bind the channel to the vm */ - gk20a_vm_get(&g->mm.ce.vm); - ce_ctx->vm = ce_ctx->ch->vm = &g->mm.ce.vm; - err = channel_gk20a_commit_va(ce_ctx->ch); + err = __gk20a_vm_bind_channel(&g->mm.ce.vm, ce_ctx->ch); if (err) { gk20a_err(ce_ctx->dev, "ce: could not bind vm"); 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) if (ch->hw_sema) gk20a_semaphore_free_hw_sema(ch); - /* release channel binding to the as_share */ - if (ch_vm->as_share) - gk20a_as_release_share(ch_vm->as_share); - else - gk20a_vm_put(ch_vm); + /* + * When releasing the channel we unbind the VM - so release the ref. + */ + gk20a_vm_put(ch_vm); spin_lock(&ch->update_fn_lock); ch->update_fn = NULL; @@ -2252,14 +2251,11 @@ static int gk20a_channel_add_job(struct channel_gk20a *c, int err = 0, num_mapped_buffers = 0; bool pre_alloc_enabled = channel_gk20a_is_prealloc_enabled(c); - /* job needs reference to this vm (released in channel_update) */ - gk20a_vm_get(vm); - if (!skip_buffer_refcounting) { err = gk20a_vm_get_buffers(vm, &mapped_buffers, &num_mapped_buffers); if (err) - goto err_put_vm; + return err; } /* 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, err_put_buffers: gk20a_vm_put_buffers(vm, mapped_buffers, num_mapped_buffers); -err_put_vm: - gk20a_vm_put(vm); return err; } @@ -2385,8 +2379,6 @@ static void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, gk20a_free_priv_cmdbuf(c, job->wait_cmd); gk20a_free_priv_cmdbuf(c, job->incr_cmd); - /* job is done. release its vm reference (taken in add_job) */ - gk20a_vm_put(vm); /* another bookkeeping taken in add_job. caller must hold a ref * so this wouldn't get freed here. */ 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) return -ENOMEM; vm->sema_pool = gk20a_semaphore_pool_alloc(sema_sea); - if (!vm->sema_pool) { - gk20a_vm_put(vm); + if (!vm->sema_pool) return -ENOMEM; - } /* * 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) gk20a_semaphore_pool_unmap(vm->sema_pool, vm); nvgpu_free(vm->vma[gmmu_page_size_small], vm->sema_pool->gpu_va); - gk20a_vm_put(vm); + return err; } return 0; @@ -4632,12 +4630,10 @@ int gk20a_vm_release_share(struct gk20a_as_share *as_share) gk20a_dbg_fn(""); vm->as_share = NULL; + as_share->vm = NULL; - /* put as reference to vm */ gk20a_vm_put(vm); - as_share->vm = NULL; - return 0; } @@ -4792,14 +4788,13 @@ int gk20a_vm_free_space(struct gk20a_as_share *as_share, return err; } -int gk20a_vm_bind_channel(struct gk20a_as_share *as_share, - struct channel_gk20a *ch) +int __gk20a_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch) { int err = 0; - struct vm_gk20a *vm = as_share->vm; gk20a_dbg_fn(""); + gk20a_vm_get(vm); ch->vm = vm; err = channel_gk20a_commit_va(ch); if (err) @@ -4808,6 +4803,12 @@ int gk20a_vm_bind_channel(struct gk20a_as_share *as_share, return err; } +int gk20a_vm_bind_channel(struct gk20a_as_share *as_share, + struct channel_gk20a *ch) +{ + return __gk20a_vm_bind_channel(as_share->vm, ch); +} + int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) { 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, struct nvgpu_as_free_space_args *args); int gk20a_vm_bind_channel(struct gk20a_as_share *as_share, struct channel_gk20a *ch); +int __gk20a_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch); /* batching eliminates redundant cache flushes and invalidates */ void 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, err = -ENOMEM; } + if (ch->vm) + gk20a_vm_get(ch->vm); + return err; } -- cgit v1.2.2