diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-07-20 03:09:12 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-08-10 14:17:58 -0400 |
commit | 59a115f3fe6076de4c9af69de836cc82d6430544 (patch) | |
tree | 18af9e6080ee1306b1737ac74f392d88150e7a3c | |
parent | 118809f4bd07af20df2b6c012828834695a5fccf (diff) |
gpu: nvgpu: post bpt events after processing
We currently post bpt events (bpt.int and bpt.pause) even
before we process and clear the interrupts and this
could cause races with UMD
Fix this by posting bpt events only after we are done
processing the interrupts
Bug 200209410
Change-Id: Ic3ff7148189fccb796cb6175d6d22ac25a4097fb
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1184109
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 78 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 3 |
3 files changed, 50 insertions, 34 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 7eb98a2c..6f735af9 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -264,7 +264,8 @@ struct gpu_ops { | |||
264 | bool *early_exit, bool *ignore_debugger); | 264 | bool *early_exit, bool *ignore_debugger); |
265 | u32 (*mask_hww_warp_esr)(u32 hww_warp_esr); | 265 | u32 (*mask_hww_warp_esr)(u32 hww_warp_esr); |
266 | int (*handle_sm_exception)(struct gk20a *g, u32 gpc, u32 tpc, | 266 | int (*handle_sm_exception)(struct gk20a *g, u32 gpc, u32 tpc, |
267 | bool *post_event, struct channel_gk20a *fault_ch); | 267 | bool *post_event, struct channel_gk20a *fault_ch, |
268 | u32 *hww_global_esr); | ||
268 | int (*handle_tex_exception)(struct gk20a *g, u32 gpc, u32 tpc, | 269 | int (*handle_tex_exception)(struct gk20a *g, u32 gpc, u32 tpc, |
269 | bool *post_event); | 270 | bool *post_event); |
270 | void (*create_gr_sysfs)(struct device *dev); | 271 | void (*create_gr_sysfs)(struct device *dev); |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 979f69ba..271c384a 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -5869,7 +5869,8 @@ fail: | |||
5869 | } | 5869 | } |
5870 | 5870 | ||
5871 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | 5871 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, |
5872 | bool *post_event, struct channel_gk20a *fault_ch) | 5872 | bool *post_event, struct channel_gk20a *fault_ch, |
5873 | u32 *hww_global_esr) | ||
5873 | { | 5874 | { |
5874 | int ret = 0; | 5875 | int ret = 0; |
5875 | bool do_warp_sync = false, early_exit = false, ignore_debugger = false; | 5876 | bool do_warp_sync = false, early_exit = false, ignore_debugger = false; |
@@ -5901,35 +5902,12 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
5901 | return -EFAULT; | 5902 | return -EFAULT; |
5902 | } | 5903 | } |
5903 | 5904 | ||
5904 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f()) { | ||
5905 | if (gk20a_is_channel_marked_as_tsg(fault_ch)) { | ||
5906 | struct tsg_gk20a *tsg = &g->fifo.tsg[fault_ch->tsgid]; | ||
5907 | |||
5908 | gk20a_tsg_event_id_post_event(tsg, | ||
5909 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
5910 | } else { | ||
5911 | gk20a_channel_event_id_post_event(fault_ch, | ||
5912 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
5913 | } | ||
5914 | } | ||
5915 | |||
5916 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f()) { | ||
5917 | if (gk20a_is_channel_marked_as_tsg(fault_ch)) { | ||
5918 | struct tsg_gk20a *tsg = &g->fifo.tsg[fault_ch->tsgid]; | ||
5919 | |||
5920 | gk20a_tsg_event_id_post_event(tsg, | ||
5921 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
5922 | } else { | ||
5923 | gk20a_channel_event_id_post_event(fault_ch, | ||
5924 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
5925 | } | ||
5926 | } | ||
5927 | |||
5928 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5905 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5929 | "sm hww global %08x warp %08x", global_esr, warp_esr); | 5906 | "sm hww global %08x warp %08x", global_esr, warp_esr); |
5930 | 5907 | ||
5931 | gr_gk20a_elpg_protected_call(g, | 5908 | gr_gk20a_elpg_protected_call(g, |
5932 | g->ops.gr.record_sm_error_state(g, gpc, tpc)); | 5909 | g->ops.gr.record_sm_error_state(g, gpc, tpc)); |
5910 | *hww_global_esr = global_esr; | ||
5933 | 5911 | ||
5934 | if (g->ops.gr.pre_process_sm_exception) { | 5912 | if (g->ops.gr.pre_process_sm_exception) { |
5935 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, | 5913 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, |
@@ -5946,7 +5924,7 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
5946 | 5924 | ||
5947 | if (early_exit) { | 5925 | if (early_exit) { |
5948 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5926 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5949 | "returning early, skipping event posting"); | 5927 | "returning early"); |
5950 | return ret; | 5928 | return ret; |
5951 | } | 5929 | } |
5952 | 5930 | ||
@@ -6009,7 +5987,8 @@ int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
6009 | } | 5987 | } |
6010 | 5988 | ||
6011 | static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | 5989 | static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, |
6012 | bool *post_event, struct channel_gk20a *fault_ch) | 5990 | bool *post_event, struct channel_gk20a *fault_ch, |
5991 | u32 *hww_global_esr) | ||
6013 | { | 5992 | { |
6014 | int ret = 0; | 5993 | int ret = 0; |
6015 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | 5994 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); |
@@ -6026,7 +6005,8 @@ static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
6026 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 6005 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
6027 | "GPC%d TPC%d: SM exception pending", gpc, tpc); | 6006 | "GPC%d TPC%d: SM exception pending", gpc, tpc); |
6028 | ret = g->ops.gr.handle_sm_exception(g, gpc, tpc, | 6007 | ret = g->ops.gr.handle_sm_exception(g, gpc, tpc, |
6029 | post_event, fault_ch); | 6008 | post_event, fault_ch, |
6009 | hww_global_esr); | ||
6030 | } | 6010 | } |
6031 | 6011 | ||
6032 | /* check if a tex exeption is pending */ | 6012 | /* check if a tex exeption is pending */ |
@@ -6041,7 +6021,7 @@ static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
6041 | } | 6021 | } |
6042 | 6022 | ||
6043 | static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | 6023 | static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, |
6044 | struct channel_gk20a *fault_ch) | 6024 | struct channel_gk20a *fault_ch, u32 *hww_global_esr) |
6045 | { | 6025 | { |
6046 | int ret = 0; | 6026 | int ret = 0; |
6047 | u32 gpc_offset, tpc_offset, gpc, tpc; | 6027 | u32 gpc_offset, tpc_offset, gpc, tpc; |
@@ -6081,7 +6061,7 @@ static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | |||
6081 | gpc_offset + tpc_offset); | 6061 | gpc_offset + tpc_offset); |
6082 | 6062 | ||
6083 | ret = gk20a_gr_handle_tpc_exception(g, gpc, tpc, | 6063 | ret = gk20a_gr_handle_tpc_exception(g, gpc, tpc, |
6084 | post_event, fault_ch); | 6064 | post_event, fault_ch, hww_global_esr); |
6085 | 6065 | ||
6086 | /* clear the hwws, also causes tpc and gpc | 6066 | /* clear the hwws, also causes tpc and gpc |
6087 | * exceptions to be cleared */ | 6067 | * exceptions to be cleared */ |
@@ -6092,6 +6072,35 @@ static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | |||
6092 | return ret; | 6072 | return ret; |
6093 | } | 6073 | } |
6094 | 6074 | ||
6075 | static int gk20a_gr_post_bpt_events(struct gk20a *g, struct channel_gk20a *ch, | ||
6076 | u32 global_esr) | ||
6077 | { | ||
6078 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f()) { | ||
6079 | if (gk20a_is_channel_marked_as_tsg(ch)) { | ||
6080 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; | ||
6081 | |||
6082 | gk20a_tsg_event_id_post_event(tsg, | ||
6083 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
6084 | } else { | ||
6085 | gk20a_channel_event_id_post_event(ch, | ||
6086 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
6087 | } | ||
6088 | } | ||
6089 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f()) { | ||
6090 | if (gk20a_is_channel_marked_as_tsg(ch)) { | ||
6091 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; | ||
6092 | |||
6093 | gk20a_tsg_event_id_post_event(tsg, | ||
6094 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
6095 | } else { | ||
6096 | gk20a_channel_event_id_post_event(ch, | ||
6097 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
6098 | } | ||
6099 | } | ||
6100 | |||
6101 | return 0; | ||
6102 | } | ||
6103 | |||
6095 | int gk20a_gr_isr(struct gk20a *g) | 6104 | int gk20a_gr_isr(struct gk20a *g) |
6096 | { | 6105 | { |
6097 | struct device *dev = dev_from_gk20a(g); | 6106 | struct device *dev = dev_from_gk20a(g); |
@@ -6101,8 +6110,10 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6101 | int need_reset = 0; | 6110 | int need_reset = 0; |
6102 | u32 gr_intr = gk20a_readl(g, gr_intr_r()); | 6111 | u32 gr_intr = gk20a_readl(g, gr_intr_r()); |
6103 | struct channel_gk20a *ch = NULL; | 6112 | struct channel_gk20a *ch = NULL; |
6113 | struct channel_gk20a *fault_ch = NULL; | ||
6104 | int tsgid = NVGPU_INVALID_TSG_ID; | 6114 | int tsgid = NVGPU_INVALID_TSG_ID; |
6105 | u32 gr_engine_id; | 6115 | u32 gr_engine_id; |
6116 | u32 global_esr = 0; | ||
6106 | 6117 | ||
6107 | gk20a_dbg_fn(""); | 6118 | gk20a_dbg_fn(""); |
6108 | gk20a_dbg(gpu_dbg_intr, "pgraph intr %08x", gr_intr); | 6119 | gk20a_dbg(gpu_dbg_intr, "pgraph intr %08x", gr_intr); |
@@ -6235,7 +6246,6 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6235 | 6246 | ||
6236 | /* check if a gpc exception has occurred */ | 6247 | /* check if a gpc exception has occurred */ |
6237 | if (exception & gr_exception_gpc_m() && need_reset == 0) { | 6248 | if (exception & gr_exception_gpc_m() && need_reset == 0) { |
6238 | struct channel_gk20a *fault_ch; | ||
6239 | bool post_event = false; | 6249 | bool post_event = false; |
6240 | 6250 | ||
6241 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "GPC exception pending"); | 6251 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "GPC exception pending"); |
@@ -6246,7 +6256,7 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6246 | 6256 | ||
6247 | /* check if any gpc has an exception */ | 6257 | /* check if any gpc has an exception */ |
6248 | need_reset |= gk20a_gr_handle_gpc_exception(g, | 6258 | need_reset |= gk20a_gr_handle_gpc_exception(g, |
6249 | &post_event, fault_ch); | 6259 | &post_event, fault_ch, &global_esr); |
6250 | 6260 | ||
6251 | /* signal clients waiting on an event */ | 6261 | /* signal clients waiting on an event */ |
6252 | if (gk20a_gr_sm_debugger_attached(g) && post_event && fault_ch) { | 6262 | if (gk20a_gr_sm_debugger_attached(g) && post_event && fault_ch) { |
@@ -6310,6 +6320,10 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6310 | gk20a_err(dev_from_gk20a(g), | 6320 | gk20a_err(dev_from_gk20a(g), |
6311 | "unhandled gr interrupt 0x%08x", gr_intr); | 6321 | "unhandled gr interrupt 0x%08x", gr_intr); |
6312 | 6322 | ||
6323 | /* Posting of BPT events should be the last thing in this function */ | ||
6324 | if (global_esr && fault_ch) | ||
6325 | gk20a_gr_post_bpt_events(g, fault_ch, global_esr); | ||
6326 | |||
6313 | if (ch) | 6327 | if (ch) |
6314 | gk20a_channel_put(ch); | 6328 | gk20a_channel_put(ch); |
6315 | 6329 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index e1335b89..2a351bc3 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h | |||
@@ -584,7 +584,8 @@ void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); | |||
584 | int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, | 584 | int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, |
585 | u32 expect_delay); | 585 | u32 expect_delay); |
586 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | 586 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, |
587 | bool *post_event, struct channel_gk20a *fault_ch); | 587 | bool *post_event, struct channel_gk20a *fault_ch, |
588 | u32 *hww_global_esr); | ||
588 | int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, | 589 | int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, |
589 | bool *post_event); | 590 | bool *post_event); |
590 | int gr_gk20a_init_ctx_state(struct gk20a *g); | 591 | int gr_gk20a_init_ctx_state(struct gk20a *g); |