From 3d2942e41283d7efb91193f5532c7dfce546359c Mon Sep 17 00:00:00 2001 From: Vinod G Date: Mon, 15 Apr 2019 17:49:04 -0700 Subject: [PATCH] gpu: nvgpu: move nvgpu_report_gr_exception to common.gr.intr Move the nvgpu_report_gr_exception call from gr_gk20a to gr_intr.c as nvgpu_gr_intr_report_exception Move local function gk20a_gr_get_channel_from_ctx to gr_intr.c as nvgpu_gr_intr_get_channel_from_ctx JIRA NVGPU-1891 Change-Id: I21521ad50989582d8f166a98a21ea3b1dcd3bbff Signed-off-by: Vinod G Reviewed-on: https://git-master.nvidia.com/r/2098229 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/gr_intr.c | 123 ++++++++++++++++ drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 131 +----------------- drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 9 +- drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c | 16 +-- drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gv11b.c | 4 +- drivers/gpu/nvgpu/include/nvgpu/gr/gr_intr.h | 4 + drivers/gpu/nvgpu/include/nvgpu/nvgpu_err.h | 3 - 7 files changed, 142 insertions(+), 148 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/gr_intr.c b/drivers/gpu/nvgpu/common/gr/gr_intr.c index 8531b3077..c2c3ea70b 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_intr.c +++ b/drivers/gpu/nvgpu/common/gr/gr_intr.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -104,6 +105,128 @@ static int gr_intr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, return ret; } +/* Used by sw interrupt thread to translate current ctx to chid. + * Also used by regops to translate current ctx to chid and tsgid. + * For performance, we don't want to go through 128 channels every time. + * curr_ctx should be the value read from gr falcon get_current_ctx op + * A small tlb is used here to cache translation. + * + * Returned channel must be freed with gk20a_channel_put() */ +struct channel_gk20a *nvgpu_gr_intr_get_channel_from_ctx(struct gk20a *g, + u32 curr_ctx, u32 *curr_tsgid) +{ + struct fifo_gk20a *f = &g->fifo; + struct gr_gk20a *gr = &g->gr; + u32 chid; + u32 tsgid = NVGPU_INVALID_TSG_ID; + u32 i; + struct channel_gk20a *ret_ch = NULL; + + /* when contexts are unloaded from GR, the valid bit is reset + * but the instance pointer information remains intact. + * This might be called from gr_isr where contexts might be + * unloaded. No need to check ctx_valid bit + */ + + nvgpu_spinlock_acquire(&gr->ch_tlb_lock); + + /* check cache first */ + for (i = 0; i < GR_CHANNEL_MAP_TLB_SIZE; i++) { + if (gr->chid_tlb[i].curr_ctx == curr_ctx) { + chid = gr->chid_tlb[i].chid; + tsgid = gr->chid_tlb[i].tsgid; + ret_ch = gk20a_channel_from_id(g, chid); + goto unlock; + } + } + + /* slow path */ + for (chid = 0; chid < f->num_channels; chid++) { + struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); + + if (ch == NULL) { + continue; + } + + if (nvgpu_inst_block_ptr(g, &ch->inst_block) == + g->ops.gr.falcon.get_ctx_ptr(curr_ctx)) { + tsgid = ch->tsgid; + /* found it */ + ret_ch = ch; + break; + } + gk20a_channel_put(ch); + } + + if (ret_ch == NULL) { + goto unlock; + } + + /* add to free tlb entry */ + for (i = 0; i < GR_CHANNEL_MAP_TLB_SIZE; i++) { + if (gr->chid_tlb[i].curr_ctx == 0U) { + gr->chid_tlb[i].curr_ctx = curr_ctx; + gr->chid_tlb[i].chid = chid; + gr->chid_tlb[i].tsgid = tsgid; + goto unlock; + } + } + + /* no free entry, flush one */ + gr->chid_tlb[gr->channel_tlb_flush_index].curr_ctx = curr_ctx; + gr->chid_tlb[gr->channel_tlb_flush_index].chid = chid; + gr->chid_tlb[gr->channel_tlb_flush_index].tsgid = tsgid; + + gr->channel_tlb_flush_index = + (gr->channel_tlb_flush_index + 1U) & + (GR_CHANNEL_MAP_TLB_SIZE - 1U); + +unlock: + nvgpu_spinlock_release(&gr->ch_tlb_lock); + if (curr_tsgid != NULL) { + *curr_tsgid = tsgid; + } + return ret_ch; +} + +void nvgpu_gr_intr_report_exception(struct gk20a *g, u32 inst, + u32 err_type, u32 status) +{ + int ret = 0; + struct channel_gk20a *ch; + struct gr_exception_info err_info; + struct gr_err_info info; + u32 tsgid, chid, curr_ctx; + + if (g->ops.gr.err_ops.report_gr_err == NULL) { + return; + } + + tsgid = NVGPU_INVALID_TSG_ID; + curr_ctx = g->ops.gr.falcon.get_current_ctx(g); + ch = nvgpu_gr_intr_get_channel_from_ctx(g, curr_ctx, &tsgid); + chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID; + if (ch != NULL) { + gk20a_channel_put(ch); + } + + (void) memset(&err_info, 0, sizeof(err_info)); + (void) memset(&info, 0, sizeof(info)); + err_info.curr_ctx = curr_ctx; + err_info.chid = chid; + err_info.tsgid = tsgid; + err_info.status = status; + info.exception_info = &err_info; + ret = g->ops.gr.err_ops.report_gr_err(g, + NVGPU_ERR_MODULE_PGRAPH, inst, err_type, + &info); + if (ret != 0) { + nvgpu_err(g, "Failed to report PGRAPH exception: " + "inst=%u, err_type=%u, status=%u", + inst, err_type, status); + } +} + int nvgpu_gr_intr_handle_gpc_exception(struct gk20a *g, bool *post_event, struct nvgpu_gr_config *gr_config, struct channel_gk20a *fault_ch, u32 *hww_global_esr) diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index c90b6f9b4..681da7b6e 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -68,47 +68,6 @@ #include #include -static struct channel_gk20a *gk20a_gr_get_channel_from_ctx( - struct gk20a *g, u32 curr_ctx, u32 *curr_tsgid); - -void nvgpu_report_gr_exception(struct gk20a *g, u32 inst, - u32 err_type, u32 status) -{ - int ret = 0; - struct channel_gk20a *ch; - struct gr_exception_info err_info; - struct gr_err_info info; - u32 tsgid, chid, curr_ctx; - - if (g->ops.gr.err_ops.report_gr_err == NULL) { - return; - } - - tsgid = NVGPU_INVALID_TSG_ID; - curr_ctx = g->ops.gr.falcon.get_current_ctx(g); - ch = gk20a_gr_get_channel_from_ctx(g, curr_ctx, &tsgid); - chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID; - if (ch != NULL) { - gk20a_channel_put(ch); - } - - (void) memset(&err_info, 0, sizeof(err_info)); - (void) memset(&info, 0, sizeof(info)); - err_info.curr_ctx = curr_ctx; - err_info.chid = chid; - err_info.tsgid = tsgid; - err_info.status = status; - info.exception_info = &err_info; - ret = g->ops.gr.err_ops.report_gr_err(g, - NVGPU_ERR_MODULE_PGRAPH, inst, err_type, - &info); - if (ret != 0) { - nvgpu_err(g, "Failed to report PGRAPH exception: " - "inst=%u, err_type=%u, status=%u", - inst, err_type, status); - } -} - static void nvgpu_report_gr_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, u32 hww_warp_esr_status, u64 hww_warp_esr_pc) { @@ -124,7 +83,7 @@ static void nvgpu_report_gr_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, tsgid = NVGPU_INVALID_TSG_ID; curr_ctx = g->ops.gr.falcon.get_current_ctx(g); - ch = gk20a_gr_get_channel_from_ctx(g, curr_ctx, &tsgid); + ch = nvgpu_gr_intr_get_channel_from_ctx(g, curr_ctx, &tsgid); chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID; if (ch != NULL) { gk20a_channel_put(ch); @@ -428,90 +387,6 @@ static int gk20a_gr_handle_class_error(struct gk20a *g, return -EINVAL; } -/* Used by sw interrupt thread to translate current ctx to chid. - * Also used by regops to translate current ctx to chid and tsgid. - * For performance, we don't want to go through 128 channels every time. - * curr_ctx should be the value read from gr falcon get_current_ctx op - * A small tlb is used here to cache translation. - * - * Returned channel must be freed with gk20a_channel_put() */ -static struct channel_gk20a *gk20a_gr_get_channel_from_ctx( - struct gk20a *g, u32 curr_ctx, u32 *curr_tsgid) -{ - struct fifo_gk20a *f = &g->fifo; - struct gr_gk20a *gr = &g->gr; - u32 chid; - u32 tsgid = NVGPU_INVALID_TSG_ID; - u32 i; - struct channel_gk20a *ret = NULL; - - /* when contexts are unloaded from GR, the valid bit is reset - * but the instance pointer information remains intact. - * This might be called from gr_isr where contexts might be - * unloaded. No need to check ctx_valid bit - */ - - nvgpu_spinlock_acquire(&gr->ch_tlb_lock); - - /* check cache first */ - for (i = 0; i < GR_CHANNEL_MAP_TLB_SIZE; i++) { - if (gr->chid_tlb[i].curr_ctx == curr_ctx) { - chid = gr->chid_tlb[i].chid; - tsgid = gr->chid_tlb[i].tsgid; - ret = gk20a_channel_from_id(g, chid); - goto unlock; - } - } - - /* slow path */ - for (chid = 0; chid < f->num_channels; chid++) { - struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); - - if (ch == NULL) { - continue; - } - - if (nvgpu_inst_block_ptr(g, &ch->inst_block) == - g->ops.gr.falcon.get_ctx_ptr(curr_ctx)) { - tsgid = ch->tsgid; - /* found it */ - ret = ch; - break; - } - gk20a_channel_put(ch); - } - - if (ret == NULL) { - goto unlock; - } - - /* add to free tlb entry */ - for (i = 0; i < GR_CHANNEL_MAP_TLB_SIZE; i++) { - if (gr->chid_tlb[i].curr_ctx == 0U) { - gr->chid_tlb[i].curr_ctx = curr_ctx; - gr->chid_tlb[i].chid = chid; - gr->chid_tlb[i].tsgid = tsgid; - goto unlock; - } - } - - /* no free entry, flush one */ - gr->chid_tlb[gr->channel_tlb_flush_index].curr_ctx = curr_ctx; - gr->chid_tlb[gr->channel_tlb_flush_index].chid = chid; - gr->chid_tlb[gr->channel_tlb_flush_index].tsgid = tsgid; - - gr->channel_tlb_flush_index = - (gr->channel_tlb_flush_index + 1U) & - (GR_CHANNEL_MAP_TLB_SIZE - 1U); - -unlock: - nvgpu_spinlock_release(&gr->ch_tlb_lock); - if (curr_tsgid != NULL) { - *curr_tsgid = tsgid; - } - return ret; -} - int gk20a_gr_lock_down_sm(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, u32 global_esr_mask, bool check_errors) @@ -703,7 +578,7 @@ int gk20a_gr_isr(struct gk20a *g) g->ops.gr.intr.trapped_method_info(g, &isr_data); - ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); + ch = nvgpu_gr_intr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); isr_data.ch = ch; chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID; @@ -2019,7 +1894,7 @@ bool gk20a_is_channel_ctx_resident(struct channel_gk20a *ch) return false; } - curr_ch = gk20a_gr_get_channel_from_ctx(g, curr_gr_ctx, + curr_ch = nvgpu_gr_intr_get_channel_from_ctx(g, curr_gr_ctx, &curr_gr_tsgid); nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index cc880abe2..e0885eed3 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h @@ -25,13 +25,9 @@ #define GR_GK20A_H #include - -#include "mm_gk20a.h" - -#include #include -#define INVALID_MAX_WAYS 0xFFFFFFFFU +#include "mm_gk20a.h" #define GK20A_TIMEOUT_FPGA 100000U /* 100 sec */ @@ -47,6 +43,7 @@ struct nvgpu_gr_zbc; struct nvgpu_gr_hwpm_map; struct nvgpu_gr_isr_data; struct nvgpu_gr_ctx_desc; +struct dbg_session_gk20a; enum ctxsw_addr_type; @@ -256,8 +253,6 @@ int gk20a_gr_wait_for_sm_lock_down(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, u32 gk20a_gr_get_sm_hww_warp_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm); u32 gk20a_gr_get_sm_hww_global_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm); -struct dbg_session_gk20a; - bool gr_gk20a_suspend_context(struct channel_gk20a *ch); bool gr_gk20a_resume_context(struct channel_gk20a *ch); int gr_gk20a_suspend_contexts(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c index 9e90d61ff..acafc0ada 100644 --- a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c +++ b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c @@ -172,7 +172,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) u32 fe = nvgpu_readl(g, gr_fe_hww_esr_r()); u32 info = nvgpu_readl(g, gr_fe_hww_esr_info_r()); - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_FE_EXCEPTION, fe); nvgpu_err(g, "fe exception: esr 0x%08x, info 0x%08x", @@ -185,7 +185,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) if ((exception & gr_exception_memfmt_m()) != 0U) { u32 memfmt = nvgpu_readl(g, gr_memfmt_hww_esr_r()); - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_MEMFMT_EXCEPTION, memfmt); nvgpu_err(g, "memfmt exception: esr %08x", memfmt); @@ -197,7 +197,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) if ((exception & gr_exception_pd_m()) != 0U) { u32 pd = nvgpu_readl(g, gr_pd_hww_esr_r()); - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_PD_EXCEPTION, pd); nvgpu_err(g, "pd exception: esr 0x%08x", pd); @@ -209,7 +209,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) if ((exception & gr_exception_scc_m()) != 0U) { u32 scc = nvgpu_readl(g, gr_scc_hww_esr_r()); - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_SCC_EXCEPTION, scc); nvgpu_err(g, "scc exception: esr 0x%08x", scc); @@ -221,7 +221,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) if ((exception & gr_exception_ds_m()) != 0U) { u32 ds = nvgpu_readl(g, gr_ds_hww_esr_r()); - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_DS_EXCEPTION, ds); nvgpu_err(g, "ds exception: esr: 0x%08x", ds); @@ -241,7 +241,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) } else { nvgpu_err(g, "unhandled ssync exception"); } - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_SSYNC_EXCEPTION, ssync_esr); } @@ -250,7 +250,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) u32 mme = nvgpu_readl(g, gr_mme_hww_esr_r()); u32 info = nvgpu_readl(g, gr_mme_hww_esr_info_r()); - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_MME_EXCEPTION, mme); nvgpu_err(g, "mme exception: esr 0x%08x info:0x%08x", @@ -267,7 +267,7 @@ bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) if ((exception & gr_exception_sked_m()) != 0U) { u32 sked = nvgpu_readl(g, gr_sked_hww_esr_r()); - nvgpu_report_gr_exception(g, 0, + nvgpu_gr_intr_report_exception(g, 0, GPU_PGRAPH_SKED_EXCEPTION, sked); nvgpu_err(g, "sked exception: esr 0x%08x", sked); diff --git a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gv11b.c b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gv11b.c index b8e19a2ca..f427cb6e1 100644 --- a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gv11b.c +++ b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gv11b.c @@ -22,10 +22,10 @@ #include #include -#include #include #include +#include #include "gr_intr_gv11b.h" @@ -355,7 +355,7 @@ void gv11b_gr_intr_handle_tpc_mpc_exception(struct gk20a *g, u32 gpc, u32 tpc) esr = nvgpu_readl(g, gr_gpc0_tpc0_mpc_hww_esr_r() + offset); nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "mpc hww esr 0x%08x", esr); - nvgpu_report_gr_exception(g, ((gpc << 8U) | tpc), + nvgpu_gr_intr_report_exception(g, ((gpc << 8U) | tpc), GPU_PGRAPH_MPC_EXCEPTION, esr); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gr/gr_intr.h b/drivers/gpu/nvgpu/include/nvgpu/gr/gr_intr.h index 2675dc491..775f56a99 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gr/gr_intr.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gr/gr_intr.h @@ -63,4 +63,8 @@ int nvgpu_gr_intr_handle_notify_pending(struct gk20a *g, struct nvgpu_gr_isr_data *isr_data); int nvgpu_gr_intr_handle_semaphore_pending(struct gk20a *g, struct nvgpu_gr_isr_data *isr_data); +void nvgpu_gr_intr_report_exception(struct gk20a *g, u32 inst, + u32 err_type, u32 status); +struct channel_gk20a *nvgpu_gr_intr_get_channel_from_ctx(struct gk20a *g, + u32 curr_ctx, u32 *curr_tsgid); #endif /* NVGPU_GR_INTR_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_err.h b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_err.h index 735334c72..fe4869c27 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_err.h +++ b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_err.h @@ -178,9 +178,6 @@ struct gr_err_info { void nvgpu_report_host_error(struct gk20a *g, u32 inst, u32 err_id, u32 intr_info); -void nvgpu_report_gr_exception(struct gk20a *g, u32 inst, - u32 err_type, u32 status); - void nvgpu_report_ce_error(struct gk20a *g, u32 inst, u32 err_type, u32 status);