mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 02:22:34 +03:00
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>
This commit is contained in:
committed by
mobile promotions
parent
07f0798173
commit
7e403974d3
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
/* put as reference to vm */
|
||||
gk20a_vm_put(vm);
|
||||
|
||||
as_share->vm = NULL;
|
||||
|
||||
gk20a_vm_put(vm);
|
||||
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user