summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2018-11-15 08:28:11 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2019-02-05 12:04:24 -0500
commit301a9d2426b1f14d8839307fe5eabe239a973ee1 (patch)
treeb4a91048c53bfd218bb8c5e0a8e13d494f4ebd99 /drivers/gpu/nvgpu/gk20a/gr_gk20a.c
parent3794afbeb177ed0932d166d30bb2af9d9859dff9 (diff)
gpu: nvgpu: store ch ptr in gr isr data
Store a channel pointer that is either NULL or a referenced channel to avoid confusion about channel ownership. A pure channel ID is dangerous. Jira NVGPU-1460 Change-Id: I6f7b4f80cf39abc290ce9153ec6bf5b62918da97 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1955401 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> (cherry picked from commit 4e6d9afab87fce6b0a5c18b51d174ec7f800b19c in dev-kernel) Reviewed-on: https://git-master.nvidia.com/r/2008516 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit 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/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 928d80cb..58aa233f 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -5203,29 +5203,31 @@ int gk20a_gr_reset(struct gk20a *g)
5203static void gk20a_gr_set_error_notifier(struct gk20a *g, 5203static void gk20a_gr_set_error_notifier(struct gk20a *g,
5204 struct gr_gk20a_isr_data *isr_data, u32 error_notifier) 5204 struct gr_gk20a_isr_data *isr_data, u32 error_notifier)
5205{ 5205{
5206 struct fifo_gk20a *f = &g->fifo;
5207 struct channel_gk20a *ch; 5206 struct channel_gk20a *ch;
5208 struct tsg_gk20a *tsg; 5207 struct tsg_gk20a *tsg;
5209 struct channel_gk20a *ch_tsg; 5208 struct channel_gk20a *ch_tsg;
5210 5209
5211 if (isr_data->chid != FIFO_INVAL_CHANNEL_ID) { 5210 ch = isr_data->ch;
5212 ch = &f->channel[isr_data->chid]; 5211
5213 5212 if (ch == NULL) {
5214 if (gk20a_is_channel_marked_as_tsg(ch)) { 5213 return;
5215 tsg = &g->fifo.tsg[ch->tsgid]; 5214 }
5216 nvgpu_rwsem_down_read(&tsg->ch_list_lock); 5215
5217 nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, 5216 if (gk20a_is_channel_marked_as_tsg(ch)) {
5218 channel_gk20a, ch_entry) { 5217 tsg = &g->fifo.tsg[ch->tsgid];
5219 if (gk20a_channel_get(ch_tsg)) { 5218 nvgpu_rwsem_down_read(&tsg->ch_list_lock);
5220 g->ops.fifo.set_error_notifier(ch_tsg, 5219 nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list,
5221 error_notifier); 5220 channel_gk20a, ch_entry) {
5222 gk20a_channel_put(ch_tsg); 5221 if (gk20a_channel_get(ch_tsg)) {
5223 } 5222 g->ops.fifo.set_error_notifier(ch_tsg,
5223 error_notifier);
5224 gk20a_channel_put(ch_tsg);
5224 } 5225 }
5225 nvgpu_rwsem_up_read(&tsg->ch_list_lock); 5226
5226 } else {
5227 g->ops.fifo.set_error_notifier(ch, error_notifier);
5228 } 5227 }
5228 nvgpu_rwsem_up_read(&tsg->ch_list_lock);
5229 } else {
5230 g->ops.fifo.set_error_notifier(ch, error_notifier);
5229 } 5231 }
5230} 5232}
5231 5233
@@ -5285,6 +5287,8 @@ int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch,
5285{ 5287{
5286 u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r()); 5288 u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r());
5287 int ret = 0; 5289 int ret = 0;
5290 u32 chid = isr_data->ch != NULL ?
5291 isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID;
5288 5292
5289 if (gr_fecs_intr == 0U) { 5293 if (gr_fecs_intr == 0U) {
5290 return 0; 5294 return 0;
@@ -5302,7 +5306,7 @@ int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch,
5302 gr_fecs_host_int_status_watchdog_active_f()) != 0U) { 5306 gr_fecs_host_int_status_watchdog_active_f()) != 0U) {
5303 /* currently, recovery is not initiated */ 5307 /* currently, recovery is not initiated */
5304 nvgpu_err(g, "fecs watchdog triggered for channel %u, " 5308 nvgpu_err(g, "fecs watchdog triggered for channel %u, "
5305 "cannot ctxsw anymore !!", isr_data->chid); 5309 "cannot ctxsw anymore !!", chid);
5306 gk20a_fecs_dump_falcon_stats(g); 5310 gk20a_fecs_dump_falcon_stats(g);
5307 } else if ((gr_fecs_intr & 5311 } else if ((gr_fecs_intr &
5308 gr_fecs_host_int_status_ctxsw_intr_f(CTXSW_INTR0)) != 0U) { 5312 gr_fecs_host_int_status_ctxsw_intr_f(CTXSW_INTR0)) != 0U) {
@@ -5337,6 +5341,8 @@ static int gk20a_gr_handle_class_error(struct gk20a *g,
5337 struct gr_gk20a_isr_data *isr_data) 5341 struct gr_gk20a_isr_data *isr_data)
5338{ 5342{
5339 u32 gr_class_error; 5343 u32 gr_class_error;
5344 u32 chid = isr_data->ch != NULL ?
5345 isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID;
5340 5346
5341 nvgpu_log_fn(g, " "); 5347 nvgpu_log_fn(g, " ");
5342 5348
@@ -5355,7 +5361,7 @@ static int gk20a_gr_handle_class_error(struct gk20a *g,
5355 gk20a_readl(g, gr_trapped_data_mme_r())), 5361 gk20a_readl(g, gr_trapped_data_mme_r())),
5356 gr_trapped_addr_datahigh_v(isr_data->addr), 5362 gr_trapped_addr_datahigh_v(isr_data->addr),
5357 gr_trapped_addr_priv_v(isr_data->addr), 5363 gr_trapped_addr_priv_v(isr_data->addr),
5358 gr_class_error, isr_data->chid); 5364 gr_class_error, chid);
5359 5365
5360 nvgpu_err(g, "trapped data low 0x%08x", 5366 nvgpu_err(g, "trapped data low 0x%08x",
5361 gk20a_readl(g, gr_trapped_data_lo_r())); 5367 gk20a_readl(g, gr_trapped_data_lo_r()));
@@ -5370,6 +5376,9 @@ static int gk20a_gr_handle_class_error(struct gk20a *g,
5370static int gk20a_gr_handle_firmware_method(struct gk20a *g, 5376static int gk20a_gr_handle_firmware_method(struct gk20a *g,
5371 struct gr_gk20a_isr_data *isr_data) 5377 struct gr_gk20a_isr_data *isr_data)
5372{ 5378{
5379 u32 chid = isr_data->ch != NULL ?
5380 isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID;
5381
5373 nvgpu_log_fn(g, " "); 5382 nvgpu_log_fn(g, " ");
5374 5383
5375 gk20a_gr_set_error_notifier(g, isr_data, 5384 gk20a_gr_set_error_notifier(g, isr_data,
@@ -5377,15 +5386,14 @@ static int gk20a_gr_handle_firmware_method(struct gk20a *g,
5377 nvgpu_err(g, 5386 nvgpu_err(g,
5378 "firmware method 0x%08x, offset 0x%08x for channel %u", 5387 "firmware method 0x%08x, offset 0x%08x for channel %u",
5379 isr_data->class_num, isr_data->offset, 5388 isr_data->class_num, isr_data->offset,
5380 isr_data->chid); 5389 chid);
5381 return -EINVAL; 5390 return -EINVAL;
5382} 5391}
5383 5392
5384int gk20a_gr_handle_semaphore_pending(struct gk20a *g, 5393int gk20a_gr_handle_semaphore_pending(struct gk20a *g,
5385 struct gr_gk20a_isr_data *isr_data) 5394 struct gr_gk20a_isr_data *isr_data)
5386{ 5395{
5387 struct fifo_gk20a *f = &g->fifo; 5396 struct channel_gk20a *ch = isr_data->ch;
5388 struct channel_gk20a *ch = &f->channel[isr_data->chid];
5389 struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; 5397 struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid];
5390 5398
5391 g->ops.fifo.post_event_id(tsg, 5399 g->ops.fifo.post_event_id(tsg,
@@ -5419,8 +5427,7 @@ static inline bool is_valid_cyclestats_bar0_offset_gk20a(struct gk20a *g,
5419int gk20a_gr_handle_notify_pending(struct gk20a *g, 5427int gk20a_gr_handle_notify_pending(struct gk20a *g,
5420 struct gr_gk20a_isr_data *isr_data) 5428 struct gr_gk20a_isr_data *isr_data)
5421{ 5429{
5422 struct fifo_gk20a *f = &g->fifo; 5430 struct channel_gk20a *ch = isr_data->ch;
5423 struct channel_gk20a *ch = &f->channel[isr_data->chid];
5424 5431
5425#if defined(CONFIG_GK20A_CYCLE_STATS) 5432#if defined(CONFIG_GK20A_CYCLE_STATS)
5426 void *virtual_address; 5433 void *virtual_address;
@@ -5965,6 +5972,7 @@ int gk20a_gr_isr(struct gk20a *g)
5965 struct tsg_gk20a *tsg = NULL; 5972 struct tsg_gk20a *tsg = NULL;
5966 u32 gr_engine_id; 5973 u32 gr_engine_id;
5967 u32 global_esr = 0; 5974 u32 global_esr = 0;
5975 u32 chid;
5968 5976
5969 nvgpu_log_fn(g, " "); 5977 nvgpu_log_fn(g, " ");
5970 nvgpu_log(g, gpu_dbg_intr, "pgraph intr %08x", gr_intr); 5978 nvgpu_log(g, gpu_dbg_intr, "pgraph intr %08x", gr_intr);
@@ -5997,10 +6005,10 @@ int gk20a_gr_isr(struct gk20a *g)
5997 isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table); 6005 isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table);
5998 6006
5999 ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); 6007 ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid);
6000 if (ch) { 6008 isr_data.ch = ch;
6001 isr_data.chid = ch->chid; 6009 chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID;
6002 } else { 6010
6003 isr_data.chid = FIFO_INVAL_CHANNEL_ID; 6011 if (ch == NULL) {
6004 nvgpu_err(g, "ch id is INVALID 0xffffffff"); 6012 nvgpu_err(g, "ch id is INVALID 0xffffffff");
6005 } 6013 }
6006 6014
@@ -6013,7 +6021,7 @@ int gk20a_gr_isr(struct gk20a *g)
6013 "data 0x%08x 0x%08x," 6021 "data 0x%08x 0x%08x,"
6014 "ctx 0x%08x, offset 0x%08x, " 6022 "ctx 0x%08x, offset 0x%08x, "
6015 "subchannel 0x%08x, class 0x%08x", 6023 "subchannel 0x%08x, class 0x%08x",
6016 isr_data.chid, isr_data.addr, 6024 chid, isr_data.addr,
6017 isr_data.data_hi, isr_data.data_lo, 6025 isr_data.data_hi, isr_data.data_lo,
6018 isr_data.curr_ctx, isr_data.offset, 6026 isr_data.curr_ctx, isr_data.offset,
6019 isr_data.sub_chan, isr_data.class_num); 6027 isr_data.sub_chan, isr_data.class_num);
@@ -6190,10 +6198,9 @@ int gk20a_gr_isr(struct gk20a *g)
6190 nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, 6198 nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg,
6191 "GPC exception pending"); 6199 "GPC exception pending");
6192 6200
6193 fault_ch = gk20a_fifo_channel_from_chid(g, 6201 fault_ch = isr_data.ch;
6194 isr_data.chid);
6195 6202
6196 /*isr_data.chid can be ~0 and fault_ch can be NULL */ 6203 /* fault_ch can be NULL */
6197 /* check if any gpc has an exception */ 6204 /* check if any gpc has an exception */
6198 if (gk20a_gr_handle_gpc_exception(g, &post_event, 6205 if (gk20a_gr_handle_gpc_exception(g, &post_event,
6199 fault_ch, &global_esr) != 0) { 6206 fault_ch, &global_esr) != 0) {