diff options
author | Alex Waterman <alexw@nvidia.com> | 2016-11-29 19:01:41 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-02-07 17:54:02 -0500 |
commit | 7e403974d3584ab8880e42d422ee3afb7f49d6f3 (patch) | |
tree | 9103e53336d8ec70f81acab5d39c9da2107abd2e /drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |
parent | 07f07981733135f648c53acfedf03b43045fed08 (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/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 18 |
1 files changed, 5 insertions, 13 deletions
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 | ||
2294 | err_put_buffers: | 2290 | err_put_buffers: |
2295 | gk20a_vm_put_buffers(vm, mapped_buffers, num_mapped_buffers); | 2291 | gk20a_vm_put_buffers(vm, mapped_buffers, num_mapped_buffers); |
2296 | err_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); |