summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/fifo/channel.c
diff options
context:
space:
mode:
authorSeema Khowala <seemaj@nvidia.com>2018-10-19 15:08:46 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2019-02-13 16:19:37 -0500
commit220860d04383489a8e75684802a2ced1323831df (patch)
tree123e92d8b1781afa6de32bc2615ae5835b389f4d /drivers/gpu/nvgpu/common/fifo/channel.c
parent18643ac1357a845d204d6dabd98359a0ab0509a7 (diff)
gpu: nvgpu: rename has_timedout and make it thread safe
Currently has_timedout variable is protected by wmb at places where it is being set and there is no correspoding rmb whenever has_timedout variable is read. This is prone to errors for concurrent execution. This change is supposed to fix this issue. Rename has_timedout variable of channel struct to ch_timedout. Also to avoid rmb every time ch_timedout is read, ch_timedout_spinlock is added to protect ch_timedout variable for taking care of concurrent execution. Bug 2404865 Bug 2092051 Change-Id: I0bee9f50af0a48720aa8b54cbc3af97ef9f6df00 Signed-off-by: Seema Khowala <seemaj@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1930935 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> (cherry picked from commit 1f54ea09e3445d9ca3cf7a69b4967849cc9defc8 in dev-kernel) Reviewed-on: https://git-master.nvidia.com/r/2016975 GVS: Gerrit_Virtual_Submit Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/fifo/channel.c')
-rw-r--r--drivers/gpu/nvgpu/common/fifo/channel.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c
index 29720886..b5ae42d4 100644
--- a/drivers/gpu/nvgpu/common/fifo/channel.c
+++ b/drivers/gpu/nvgpu/common/fifo/channel.c
@@ -212,6 +212,24 @@ void gk20a_channel_abort_clean_up(struct channel_gk20a *ch)
212 gk20a_channel_update(ch); 212 gk20a_channel_update(ch);
213} 213}
214 214
215void gk20a_channel_set_timedout(struct channel_gk20a *ch)
216{
217 nvgpu_spinlock_acquire(&ch->ch_timedout_lock);
218 ch->ch_timedout = true;
219 nvgpu_spinlock_release(&ch->ch_timedout_lock);
220}
221
222bool gk20a_channel_check_timedout(struct channel_gk20a *ch)
223{
224 bool ch_timedout_status;
225
226 nvgpu_spinlock_acquire(&ch->ch_timedout_lock);
227 ch_timedout_status = ch->ch_timedout;
228 nvgpu_spinlock_release(&ch->ch_timedout_lock);
229
230 return ch_timedout_status;
231}
232
215void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) 233void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt)
216{ 234{
217 struct tsg_gk20a *tsg = tsg_gk20a_from_ch(ch); 235 struct tsg_gk20a *tsg = tsg_gk20a_from_ch(ch);
@@ -223,7 +241,7 @@ void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt)
223 } 241 }
224 242
225 /* make sure new kickoffs are prevented */ 243 /* make sure new kickoffs are prevented */
226 ch->has_timedout = true; 244 gk20a_channel_set_timedout(ch);
227 245
228 ch->g->ops.fifo.disable_channel(ch); 246 ch->g->ops.fifo.disable_channel(ch);
229 247
@@ -425,7 +443,7 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
425 * Set user managed syncpoint to safe state 443 * Set user managed syncpoint to safe state
426 * But it's already done if channel has timedout 444 * But it's already done if channel has timedout
427 */ 445 */
428 if (ch->has_timedout) { 446 if (gk20a_channel_check_timedout(ch)) {
429 nvgpu_channel_sync_destroy(ch->user_sync, false); 447 nvgpu_channel_sync_destroy(ch->user_sync, false);
430 } else { 448 } else {
431 nvgpu_channel_sync_destroy(ch->user_sync, true); 449 nvgpu_channel_sync_destroy(ch->user_sync, true);
@@ -711,7 +729,7 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g,
711 /* set gr host default timeout */ 729 /* set gr host default timeout */
712 ch->timeout_ms_max = gk20a_get_gr_idle_timeout(g); 730 ch->timeout_ms_max = gk20a_get_gr_idle_timeout(g);
713 ch->timeout_debug_dump = true; 731 ch->timeout_debug_dump = true;
714 ch->has_timedout = false; 732 ch->ch_timedout = false;
715 733
716 /* init kernel watchdog timeout */ 734 /* init kernel watchdog timeout */
717 ch->timeout.enabled = true; 735 ch->timeout.enabled = true;
@@ -2196,6 +2214,8 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
2196 c->referenceable = false; 2214 c->referenceable = false;
2197 nvgpu_cond_init(&c->ref_count_dec_wq); 2215 nvgpu_cond_init(&c->ref_count_dec_wq);
2198 2216
2217 nvgpu_spinlock_init(&c->ch_timedout_lock);
2218
2199#if GK20A_CHANNEL_REFCOUNT_TRACKING 2219#if GK20A_CHANNEL_REFCOUNT_TRACKING
2200 nvgpu_spinlock_init(&c->ref_actions_lock); 2220 nvgpu_spinlock_init(&c->ref_actions_lock);
2201#endif 2221#endif