diff options
author | Seema Khowala <seemaj@nvidia.com> | 2018-10-19 15:08:46 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2019-02-13 16:19:37 -0500 |
commit | 220860d04383489a8e75684802a2ced1323831df (patch) | |
tree | 123e92d8b1781afa6de32bc2615ae5835b389f4d /drivers/gpu/nvgpu/common/fifo/channel.c | |
parent | 18643ac1357a845d204d6dabd98359a0ab0509a7 (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.c | 26 |
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 | ||
215 | void 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 | |||
222 | bool 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 | |||
215 | void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) | 233 | void 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 |