summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2016-07-20 03:09:12 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-08-10 14:17:58 -0400
commit59a115f3fe6076de4c9af69de836cc82d6430544 (patch)
tree18af9e6080ee1306b1737ac74f392d88150e7a3c /drivers/gpu/nvgpu/gk20a/gr_gk20a.c
parent118809f4bd07af20df2b6c012828834695a5fccf (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>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c78
1 files changed, 46 insertions, 32 deletions
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
5871int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, 5871int 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
6011static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, 5989static 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
6043static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, 6023static 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
6075static 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
6095int gk20a_gr_isr(struct gk20a *g) 6104int 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