summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2016-12-19 06:01:43 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2016-12-27 04:24:35 -0500
commit505b442551a2e27aa3bc9e608c5a2bc9fccecbc4 (patch)
tree5b4d1d9664ab819e009fc9300784b897be035058 /drivers/gpu/nvgpu
parentf3d2dd4fd2c3d0fa3f774bcbc1d2b9ef482d7663 (diff)
gpu: nvgpu: acquire mutex for notifier read
We use &ch->error_notifier_mutex to protect writes and free of error notifier But we currently do not protect reading of notifier in gk20a_fifo_set_ctx_mmu_error() and vgpu_fifo_set_ctx_mmu_error() Add new API gk20a_set_error_notifier_locked() which is same as gk20a_set_error_notifier() but without the locks. In *_fifo_set_ctx_mmu_error() APIs, acquire the mutex explicitly, and then use this new API gk20a_set_error_notifier() will now just call gk20a_set_error_notifier_locked() within a mutex Bug 1824788 Bug 1844312 Change-Id: I1f3831dc63fe1daa761b2e17e4de3c155f505d6f Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1273471 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Richard Zhao <rizhao@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c22
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c7
-rw-r--r--drivers/gpu/nvgpu/vgpu/fifo_vgpu.c7
4 files changed, 24 insertions, 13 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 129921ad..38cb368c 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -827,11 +827,12 @@ static int gk20a_init_error_notifier(struct channel_gk20a *ch,
827 return 0; 827 return 0;
828} 828}
829 829
830void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error) 830/**
831 * gk20a_set_error_notifier_locked()
832 * Should be called with ch->error_notifier_mutex held
833 */
834void gk20a_set_error_notifier_locked(struct channel_gk20a *ch, __u32 error)
831{ 835{
832 bool notifier_set = false;
833
834 mutex_lock(&ch->error_notifier_mutex);
835 if (ch->error_notifier_ref) { 836 if (ch->error_notifier_ref) {
836 struct timespec time_data; 837 struct timespec time_data;
837 u64 nsec; 838 u64 nsec;
@@ -845,13 +846,16 @@ void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error)
845 ch->error_notifier->info32 = error; 846 ch->error_notifier->info32 = error;
846 ch->error_notifier->status = 0xffff; 847 ch->error_notifier->status = 0xffff;
847 848
848 notifier_set = true;
849 }
850 mutex_unlock(&ch->error_notifier_mutex);
851
852 if (notifier_set)
853 gk20a_err(dev_from_gk20a(ch->g), 849 gk20a_err(dev_from_gk20a(ch->g),
854 "error notifier set to %d for ch %d", error, ch->hw_chid); 850 "error notifier set to %d for ch %d", error, ch->hw_chid);
851 }
852}
853
854void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error)
855{
856 mutex_lock(&ch->error_notifier_mutex);
857 gk20a_set_error_notifier_locked(ch, error);
858 mutex_unlock(&ch->error_notifier_mutex);
855} 859}
856 860
857static void gk20a_free_error_notifiers(struct channel_gk20a *ch) 861static void gk20a_free_error_notifiers(struct channel_gk20a *ch)
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index ed0b04ee..0a0d94b7 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -235,6 +235,7 @@ void gk20a_disable_channel(struct channel_gk20a *ch);
235void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt); 235void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt);
236void gk20a_channel_abort_clean_up(struct channel_gk20a *ch); 236void gk20a_channel_abort_clean_up(struct channel_gk20a *ch);
237void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error); 237void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error);
238void gk20a_set_error_notifier_locked(struct channel_gk20a *ch, __u32 error);
238void gk20a_channel_semaphore_wakeup(struct gk20a *g, bool post_events); 239void gk20a_channel_semaphore_wakeup(struct gk20a *g, bool post_events);
239int gk20a_channel_alloc_priv_cmdbuf(struct channel_gk20a *c, u32 size, 240int gk20a_channel_alloc_priv_cmdbuf(struct channel_gk20a *c, u32 size,
240 struct priv_cmd_entry *entry); 241 struct priv_cmd_entry *entry);
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index b4fa8f0f..fb772ebd 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -1219,7 +1219,8 @@ static bool gk20a_fifo_set_ctx_mmu_error(struct gk20a *g,
1219 if (!ch) 1219 if (!ch)
1220 return verbose; 1220 return verbose;
1221 1221
1222 if (ch->error_notifier) { 1222 mutex_lock(&ch->error_notifier_mutex);
1223 if (ch->error_notifier_ref) {
1223 u32 err = ch->error_notifier->info32; 1224 u32 err = ch->error_notifier->info32;
1224 if (ch->error_notifier->status == 0xffff) { 1225 if (ch->error_notifier->status == 0xffff) {
1225 /* If error code is already set, this mmu fault 1226 /* If error code is already set, this mmu fault
@@ -1230,10 +1231,12 @@ static bool gk20a_fifo_set_ctx_mmu_error(struct gk20a *g,
1230 if (err == NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT) 1231 if (err == NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT)
1231 verbose = ch->timeout_debug_dump; 1232 verbose = ch->timeout_debug_dump;
1232 } else { 1233 } else {
1233 gk20a_set_error_notifier(ch, 1234 gk20a_set_error_notifier_locked(ch,
1234 NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT); 1235 NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT);
1235 } 1236 }
1236 } 1237 }
1238 mutex_unlock(&ch->error_notifier_mutex);
1239
1237 /* mark channel as faulted */ 1240 /* mark channel as faulted */
1238 ch->has_timedout = true; 1241 ch->has_timedout = true;
1239 wmb(); 1242 wmb();
diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
index 5ffc6a00..e9a2d582 100644
--- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
@@ -678,17 +678,20 @@ static int vgpu_fifo_force_reset_ch(struct channel_gk20a *ch,
678static void vgpu_fifo_set_ctx_mmu_error(struct gk20a *g, 678static void vgpu_fifo_set_ctx_mmu_error(struct gk20a *g,
679 struct channel_gk20a *ch) 679 struct channel_gk20a *ch)
680{ 680{
681 if (ch->error_notifier) { 681 mutex_lock(&ch->error_notifier_mutex);
682 if (ch->error_notifier_ref) {
682 if (ch->error_notifier->status == 0xffff) { 683 if (ch->error_notifier->status == 0xffff) {
683 /* If error code is already set, this mmu fault 684 /* If error code is already set, this mmu fault
684 * was triggered as part of recovery from other 685 * was triggered as part of recovery from other
685 * error condition. 686 * error condition.
686 * Don't overwrite error flag. */ 687 * Don't overwrite error flag. */
687 } else { 688 } else {
688 gk20a_set_error_notifier(ch, 689 gk20a_set_error_notifier_locked(ch,
689 NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT); 690 NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT);
690 } 691 }
691 } 692 }
693 mutex_unlock(&ch->error_notifier_mutex);
694
692 /* mark channel as faulted */ 695 /* mark channel as faulted */
693 ch->has_timedout = true; 696 ch->has_timedout = true;
694 wmb(); 697 wmb();