mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: gk20a: add submit_lock
Add submit mutex lock to avoid race conditions between submitting a job, removing a job and submitting WFI With this lock make below operations atomic : during submit_gpfifo() - 1. getting new syncpt 2. inserting syncpt increment 3. submitting gpfifo 4. setting job completion interrupt during submit_wfi() - 1. getting new syncpt 2. inserting syncpt increment when idle during channel_update() - 1. checking the submit job completion 2. freeing the job if it is completed Bug 1305024 Change-Id: I0e3c0b8906d83fd59642344626ffdf24fad2aaab Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/397670 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
Dan Willemsen
parent
9984dff233
commit
d4030081a8
@@ -1268,12 +1268,6 @@ static int gk20a_channel_submit_wfi(struct channel_gk20a *c)
|
|||||||
if (c->has_timedout)
|
if (c->has_timedout)
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
|
|
||||||
if (!c->sync) {
|
|
||||||
c->sync = gk20a_channel_sync_create(c);
|
|
||||||
if (!c->sync)
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_gp_get(g, c);
|
update_gp_get(g, c);
|
||||||
free_count = gp_free_count(c);
|
free_count = gp_free_count(c);
|
||||||
if (unlikely(!free_count)) {
|
if (unlikely(!free_count)) {
|
||||||
@@ -1282,9 +1276,21 @@ static int gk20a_channel_submit_wfi(struct channel_gk20a *c)
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&c->submit_lock);
|
||||||
|
|
||||||
|
if (!c->sync) {
|
||||||
|
c->sync = gk20a_channel_sync_create(c);
|
||||||
|
if (!c->sync) {
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = c->sync->incr_wfi(c->sync, &cmd, &c->last_submit_fence);
|
err = c->sync->incr_wfi(c->sync, &cmd, &c->last_submit_fence);
|
||||||
if (unlikely(err))
|
if (unlikely(err)) {
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
WARN_ON(!c->last_submit_fence.wfi);
|
WARN_ON(!c->last_submit_fence.wfi);
|
||||||
|
|
||||||
@@ -1301,6 +1307,8 @@ static int gk20a_channel_submit_wfi(struct channel_gk20a *c)
|
|||||||
c->userd_gpu_va + 4 * ram_userd_gp_put_w(),
|
c->userd_gpu_va + 4 * ram_userd_gp_put_w(),
|
||||||
c->gpfifo.put);
|
c->gpfifo.put);
|
||||||
|
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
|
|
||||||
gk20a_dbg_info("post-submit put %d, get %d, size %d",
|
gk20a_dbg_info("post-submit put %d, get %d, size %d",
|
||||||
c->gpfifo.put, c->gpfifo.get, c->gpfifo.entry_num);
|
c->gpfifo.put, c->gpfifo.get, c->gpfifo.entry_num);
|
||||||
|
|
||||||
@@ -1393,6 +1401,7 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
|
|||||||
|
|
||||||
wake_up(&c->submit_wq);
|
wake_up(&c->submit_wq);
|
||||||
|
|
||||||
|
mutex_lock(&c->submit_lock);
|
||||||
mutex_lock(&c->jobs_lock);
|
mutex_lock(&c->jobs_lock);
|
||||||
list_for_each_entry_safe(job, n, &c->jobs, list) {
|
list_for_each_entry_safe(job, n, &c->jobs, list) {
|
||||||
bool completed = WARN_ON(!c->sync) ||
|
bool completed = WARN_ON(!c->sync) ||
|
||||||
@@ -1411,6 +1420,7 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
|
|||||||
gk20a_idle(g->dev);
|
gk20a_idle(g->dev);
|
||||||
}
|
}
|
||||||
mutex_unlock(&c->jobs_lock);
|
mutex_unlock(&c->jobs_lock);
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
|
|
||||||
for (i = 0; i < nr_completed; i++)
|
for (i = 0; i < nr_completed; i++)
|
||||||
gk20a_idle(c->g->dev);
|
gk20a_idle(c->g->dev);
|
||||||
@@ -1452,12 +1462,6 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
|||||||
!fence)
|
!fence)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!c->sync) {
|
|
||||||
c->sync = gk20a_channel_sync_create(c);
|
|
||||||
if (!c->sync)
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
/* update debug settings */
|
/* update debug settings */
|
||||||
if (g->ops.ltc.sync_debugfs)
|
if (g->ops.ltc.sync_debugfs)
|
||||||
@@ -1510,6 +1514,17 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
|||||||
goto clean_up;
|
goto clean_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&c->submit_lock);
|
||||||
|
|
||||||
|
if (!c->sync) {
|
||||||
|
c->sync = gk20a_channel_sync_create(c);
|
||||||
|
if (!c->sync) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* optionally insert syncpt wait in the beginning of gpfifo submission
|
* optionally insert syncpt wait in the beginning of gpfifo submission
|
||||||
* when user requested and the wait hasn't expired.
|
* when user requested and the wait hasn't expired.
|
||||||
@@ -1525,8 +1540,10 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
|||||||
err = c->sync->wait_syncpt(c->sync, fence->syncpt_id,
|
err = c->sync->wait_syncpt(c->sync, fence->syncpt_id,
|
||||||
fence->value, &wait_cmd);
|
fence->value, &wait_cmd);
|
||||||
}
|
}
|
||||||
if (err)
|
if (err) {
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
goto clean_up;
|
goto clean_up;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* always insert syncpt increment at end of gpfifo submission
|
/* always insert syncpt increment at end of gpfifo submission
|
||||||
@@ -1544,8 +1561,10 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
|||||||
else
|
else
|
||||||
err = c->sync->incr(c->sync, &incr_cmd,
|
err = c->sync->incr(c->sync, &incr_cmd,
|
||||||
&c->last_submit_fence);
|
&c->last_submit_fence);
|
||||||
if (err)
|
if (err) {
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
goto clean_up;
|
goto clean_up;
|
||||||
|
}
|
||||||
|
|
||||||
if (wait_cmd) {
|
if (wait_cmd) {
|
||||||
c->gpfifo.cpu_va[c->gpfifo.put].entry0 =
|
c->gpfifo.cpu_va[c->gpfifo.put].entry0 =
|
||||||
@@ -1587,12 +1606,6 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
|||||||
incr_cmd->gp_put = c->gpfifo.put;
|
incr_cmd->gp_put = c->gpfifo.put;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_gk20a_channel_submitted_gpfifo(c->g->dev->name,
|
|
||||||
c->hw_chid,
|
|
||||||
num_entries,
|
|
||||||
flags,
|
|
||||||
fence->syncpt_id, fence->value);
|
|
||||||
|
|
||||||
/* TODO! Check for errors... */
|
/* TODO! Check for errors... */
|
||||||
gk20a_channel_add_job(c, &c->last_submit_fence);
|
gk20a_channel_add_job(c, &c->last_submit_fence);
|
||||||
|
|
||||||
@@ -1601,6 +1614,14 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
|||||||
c->userd_gpu_va + 4 * ram_userd_gp_put_w(),
|
c->userd_gpu_va + 4 * ram_userd_gp_put_w(),
|
||||||
c->gpfifo.put);
|
c->gpfifo.put);
|
||||||
|
|
||||||
|
mutex_unlock(&c->submit_lock);
|
||||||
|
|
||||||
|
trace_gk20a_channel_submitted_gpfifo(c->g->dev->name,
|
||||||
|
c->hw_chid,
|
||||||
|
num_entries,
|
||||||
|
flags,
|
||||||
|
fence->syncpt_id, fence->value);
|
||||||
|
|
||||||
gk20a_dbg_info("post-submit put %d, get %d, size %d",
|
gk20a_dbg_info("post-submit put %d, get %d, size %d",
|
||||||
c->gpfifo.put, c->gpfifo.get, c->gpfifo.entry_num);
|
c->gpfifo.put, c->gpfifo.get, c->gpfifo.entry_num);
|
||||||
|
|
||||||
@@ -1629,6 +1650,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
|
|||||||
c->bound = false;
|
c->bound = false;
|
||||||
c->remove_support = gk20a_remove_channel_support;
|
c->remove_support = gk20a_remove_channel_support;
|
||||||
mutex_init(&c->jobs_lock);
|
mutex_init(&c->jobs_lock);
|
||||||
|
mutex_init(&c->submit_lock);
|
||||||
INIT_LIST_HEAD(&c->jobs);
|
INIT_LIST_HEAD(&c->jobs);
|
||||||
#if defined(CONFIG_GK20A_CYCLE_STATS)
|
#if defined(CONFIG_GK20A_CYCLE_STATS)
|
||||||
mutex_init(&c->cyclestate.cyclestate_buffer_mutex);
|
mutex_init(&c->cyclestate.cyclestate_buffer_mutex);
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ struct channel_gk20a {
|
|||||||
|
|
||||||
struct list_head jobs;
|
struct list_head jobs;
|
||||||
struct mutex jobs_lock;
|
struct mutex jobs_lock;
|
||||||
|
struct mutex submit_lock;
|
||||||
|
|
||||||
struct vm_gk20a *vm;
|
struct vm_gk20a *vm;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user