From 4e6d9afab87fce6b0a5c18b51d174ec7f800b19c Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Thu, 15 Nov 2018 15:28:11 +0200 Subject: [PATCH] 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 Reviewed-on: https://git-master.nvidia.com/r/1955401 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 70 ++++++++++++++++-------------- drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 2 +- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 2f3a01194..8dae1179d 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -5028,29 +5028,30 @@ int gk20a_gr_reset(struct gk20a *g) static void gk20a_gr_set_error_notifier(struct gk20a *g, struct gr_gk20a_isr_data *isr_data, u32 error_notifier) { - struct fifo_gk20a *f = &g->fifo; struct channel_gk20a *ch; struct tsg_gk20a *tsg; struct channel_gk20a *ch_tsg; - if (isr_data->chid != FIFO_INVAL_CHANNEL_ID) { - ch = &f->channel[isr_data->chid]; + ch = isr_data->ch; - if (gk20a_is_channel_marked_as_tsg(ch)) { - tsg = &g->fifo.tsg[ch->tsgid]; - nvgpu_rwsem_down_read(&tsg->ch_list_lock); - nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, - channel_gk20a, ch_entry) { - if (gk20a_channel_get(ch_tsg) != NULL) { - g->ops.fifo.set_error_notifier(ch_tsg, - error_notifier); - gk20a_channel_put(ch_tsg); - } + if (ch == NULL) { + return; + } + + if (gk20a_is_channel_marked_as_tsg(ch)) { + tsg = &g->fifo.tsg[ch->tsgid]; + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch_tsg) != NULL) { + g->ops.fifo.set_error_notifier(ch_tsg, + error_notifier); + gk20a_channel_put(ch_tsg); } - nvgpu_rwsem_up_read(&tsg->ch_list_lock); - } else { - g->ops.fifo.set_error_notifier(ch, error_notifier); } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + } else { + g->ops.fifo.set_error_notifier(ch, error_notifier); } } @@ -5110,6 +5111,8 @@ int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch, { u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r()); int ret = 0; + u32 chid = isr_data->ch != NULL ? + isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; if (gr_fecs_intr == 0U) { return 0; @@ -5128,12 +5131,12 @@ int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch, gr_fecs_host_int_status_watchdog_active_f()) != 0U) { /* currently, recovery is not initiated */ nvgpu_err(g, "fecs watchdog triggered for channel %u, " - "cannot ctxsw anymore !!", isr_data->chid); + "cannot ctxsw anymore !!", chid); g->ops.gr.dump_gr_falcon_stats(g); } else { nvgpu_err(g, "fecs error interrupt 0x%08x for channel %u", - gr_fecs_intr, isr_data->chid); + gr_fecs_intr, chid); } gk20a_writel(g, gr_fecs_host_int_clear_r(), gr_fecs_intr); @@ -5144,6 +5147,8 @@ static int gk20a_gr_handle_class_error(struct gk20a *g, struct gr_gk20a_isr_data *isr_data) { u32 gr_class_error; + u32 chid = isr_data->ch != NULL ? + isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; nvgpu_log_fn(g, " "); @@ -5162,7 +5167,7 @@ static int gk20a_gr_handle_class_error(struct gk20a *g, gk20a_readl(g, gr_trapped_data_mme_r())), gr_trapped_addr_datahigh_v(isr_data->addr), gr_trapped_addr_priv_v(isr_data->addr), - gr_class_error, isr_data->chid); + gr_class_error, chid); nvgpu_err(g, "trapped data low 0x%08x", gk20a_readl(g, gr_trapped_data_lo_r())); @@ -5177,6 +5182,9 @@ static int gk20a_gr_handle_class_error(struct gk20a *g, static int gk20a_gr_handle_firmware_method(struct gk20a *g, struct gr_gk20a_isr_data *isr_data) { + u32 chid = isr_data->ch != NULL ? + isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; + nvgpu_log_fn(g, " "); gk20a_gr_set_error_notifier(g, isr_data, @@ -5184,15 +5192,14 @@ static int gk20a_gr_handle_firmware_method(struct gk20a *g, nvgpu_err(g, "firmware method 0x%08x, offset 0x%08x for channel %u", isr_data->class_num, isr_data->offset, - isr_data->chid); + chid); return -EINVAL; } int gk20a_gr_handle_semaphore_pending(struct gk20a *g, struct gr_gk20a_isr_data *isr_data) { - struct fifo_gk20a *f = &g->fifo; - struct channel_gk20a *ch = &f->channel[isr_data->chid]; + struct channel_gk20a *ch = isr_data->ch; struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; g->ops.fifo.post_event_id(tsg, @@ -5226,8 +5233,7 @@ static inline bool is_valid_cyclestats_bar0_offset_gk20a(struct gk20a *g, int gk20a_gr_handle_notify_pending(struct gk20a *g, struct gr_gk20a_isr_data *isr_data) { - struct fifo_gk20a *f = &g->fifo; - struct channel_gk20a *ch = &f->channel[isr_data->chid]; + struct channel_gk20a *ch = isr_data->ch; #if defined(CONFIG_GK20A_CYCLE_STATS) void *virtual_address; @@ -5774,6 +5780,7 @@ int gk20a_gr_isr(struct gk20a *g) struct tsg_gk20a *tsg = NULL; u32 gr_engine_id; u32 global_esr = 0; + u32 chid; nvgpu_log_fn(g, " "); nvgpu_log(g, gpu_dbg_intr, "pgraph intr %08x", gr_intr); @@ -5806,10 +5813,10 @@ int gk20a_gr_isr(struct gk20a *g) isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table); ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); - if (ch != NULL) { - isr_data.chid = ch->chid; - } else { - isr_data.chid = FIFO_INVAL_CHANNEL_ID; + isr_data.ch = ch; + chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID; + + if (ch == NULL) { nvgpu_err(g, "ch id is INVALID 0xffffffff"); } @@ -5822,7 +5829,7 @@ int gk20a_gr_isr(struct gk20a *g) "data 0x%08x 0x%08x," "ctx 0x%08x, offset 0x%08x, " "subchannel 0x%08x, class 0x%08x", - isr_data.chid, isr_data.addr, + chid, isr_data.addr, isr_data.data_hi, isr_data.data_lo, isr_data.curr_ctx, isr_data.offset, isr_data.sub_chan, isr_data.class_num); @@ -5999,10 +6006,9 @@ int gk20a_gr_isr(struct gk20a *g) nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "GPC exception pending"); - fault_ch = gk20a_fifo_channel_from_chid(g, - isr_data.chid); + fault_ch = isr_data.ch; - /*isr_data.chid can be ~0 and fault_ch can be NULL */ + /* fault_ch can be NULL */ /* check if any gpc has an exception */ if (gk20a_gr_handle_gpc_exception(g, &post_event, fault_ch, &global_esr) != 0) { diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 3fb3858ce..98fe3301e 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h @@ -234,7 +234,7 @@ struct gr_gk20a_isr_data { u32 data_lo; u32 data_hi; u32 curr_ctx; - u32 chid; + struct channel_gk20a *ch; u32 offset; u32 sub_chan; u32 class_num;