diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index f9b293964..c2a21b22f 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -514,8 +514,8 @@ void gk20a_channel_abort_clean_up(struct channel_gk20a *ch) while (tmp_get != put) { job = &ch->joblist.pre_alloc.jobs[tmp_get]; if (job->post_fence->semaphore) { - gk20a_semaphore_release( - job->post_fence->semaphore); + __gk20a_semaphore_release( + job->post_fence->semaphore, true); released_job_semaphore = true; } tmp_get = (tmp_get + 1) % ch->joblist.pre_alloc.length; @@ -524,8 +524,8 @@ void gk20a_channel_abort_clean_up(struct channel_gk20a *ch) list_for_each_entry_safe(job, n, &ch->joblist.dynamic.jobs, list) { if (job->post_fence->semaphore) { - gk20a_semaphore_release( - job->post_fence->semaphore); + __gk20a_semaphore_release( + job->post_fence->semaphore, true); released_job_semaphore = true; } } diff --git a/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h b/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h index c73d3c057..cf724fdb4 100644 --- a/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h @@ -249,9 +249,11 @@ static inline u32 gk20a_semaphore_next_value(struct gk20a_semaphore *s) } /* - * Note - if you call this then any prior semaphores will also be released. + * If @force is set then this will not wait for the underlying semaphore to + * catch up to the passed semaphore. */ -static inline void gk20a_semaphore_release(struct gk20a_semaphore *s) +static inline void __gk20a_semaphore_release(struct gk20a_semaphore *s, + bool force) { u32 current_val; u32 val = gk20a_semaphore_get_value(s); @@ -264,6 +266,8 @@ static inline void gk20a_semaphore_release(struct gk20a_semaphore *s) * TODO: tune the wait a little better. */ while ((current_val = gk20a_semaphore_read(s)) < (val - 1)) { + if (force) + break; msleep(100); attempts += 1; if (attempts > 100) { @@ -285,6 +289,11 @@ static inline void gk20a_semaphore_release(struct gk20a_semaphore *s) s->hw_sema->ch->hw_chid, val); } +static inline void gk20a_semaphore_release(struct gk20a_semaphore *s) +{ + __gk20a_semaphore_release(s, false); +} + /* * Configure a software based increment on this semaphore. This is useful for * when we want the GPU to wait on a SW event before processing a channel.