From 220860d04383489a8e75684802a2ced1323831df Mon Sep 17 00:00:00 2001 From: Seema Khowala Date: Fri, 19 Oct 2018 12:08:46 -0700 Subject: 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 Reviewed-on: https://git-master.nvidia.com/r/1930935 Signed-off-by: Debarshi Dutta (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 Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/channel.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/nvgpu/common/fifo/channel.c') 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) gk20a_channel_update(ch); } +void gk20a_channel_set_timedout(struct channel_gk20a *ch) +{ + nvgpu_spinlock_acquire(&ch->ch_timedout_lock); + ch->ch_timedout = true; + nvgpu_spinlock_release(&ch->ch_timedout_lock); +} + +bool gk20a_channel_check_timedout(struct channel_gk20a *ch) +{ + bool ch_timedout_status; + + nvgpu_spinlock_acquire(&ch->ch_timedout_lock); + ch_timedout_status = ch->ch_timedout; + nvgpu_spinlock_release(&ch->ch_timedout_lock); + + return ch_timedout_status; +} + void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) { struct tsg_gk20a *tsg = tsg_gk20a_from_ch(ch); @@ -223,7 +241,7 @@ void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) } /* make sure new kickoffs are prevented */ - ch->has_timedout = true; + gk20a_channel_set_timedout(ch); ch->g->ops.fifo.disable_channel(ch); @@ -425,7 +443,7 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) * Set user managed syncpoint to safe state * But it's already done if channel has timedout */ - if (ch->has_timedout) { + if (gk20a_channel_check_timedout(ch)) { nvgpu_channel_sync_destroy(ch->user_sync, false); } else { nvgpu_channel_sync_destroy(ch->user_sync, true); @@ -711,7 +729,7 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, /* set gr host default timeout */ ch->timeout_ms_max = gk20a_get_gr_idle_timeout(g); ch->timeout_debug_dump = true; - ch->has_timedout = false; + ch->ch_timedout = false; /* init kernel watchdog timeout */ ch->timeout.enabled = true; @@ -2196,6 +2214,8 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid) c->referenceable = false; nvgpu_cond_init(&c->ref_count_dec_wq); + nvgpu_spinlock_init(&c->ch_timedout_lock); + #if GK20A_CHANNEL_REFCOUNT_TRACKING nvgpu_spinlock_init(&c->ref_actions_lock); #endif -- cgit v1.2.2