From e9c00c0da9c85acdc776c5ee1f09dfad388eac09 Mon Sep 17 00:00:00 2001 From: Nicolas Benech Date: Thu, 17 Jan 2019 18:07:35 -0500 Subject: [PATCH] gpu: nvgpu: add error codes to mm_l2_flush gv11b_mm_l2_flush was not checking error codes from the various functions it was calling. MISRA Rule-17.7 requires the return value of all functions to be used. This patch now checks return values and propagates the error upstream. JIRA NVGPU-677 Change-Id: I9005c6d3a406f9665d318014d21a1da34f87ca30 Signed-off-by: Nicolas Benech Reviewed-on: https://git-master.nvidia.com/r/1998809 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/global_ctx.c | 4 +- drivers/gpu/nvgpu/common/ltc/ltc_gp10b.c | 4 +- drivers/gpu/nvgpu/common/mm/gmmu/page_table.c | 8 +++- drivers/gpu/nvgpu/common/mm/mm.c | 10 ++++- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 37 ++++++++++++++----- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 6 ++- drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 2 +- drivers/gpu/nvgpu/gv11b/mm_gv11b.c | 36 ++++++++++++++---- drivers/gpu/nvgpu/gv11b/mm_gv11b.h | 2 +- drivers/gpu/nvgpu/gv11b/subctx_gv11b.c | 9 ++++- drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 2 +- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 12 ++++-- drivers/gpu/nvgpu/vgpu/mm_vgpu.c | 12 +++--- drivers/gpu/nvgpu/vgpu/mm_vgpu.h | 2 +- 14 files changed, 107 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/global_ctx.c b/drivers/gpu/nvgpu/common/gr/global_ctx.c index 1e88891e7..db674bf93 100644 --- a/drivers/gpu/nvgpu/common/gr/global_ctx.c +++ b/drivers/gpu/nvgpu/common/gr/global_ctx.c @@ -278,7 +278,9 @@ void nvgpu_gr_global_ctx_load_local_golden_image(struct gk20a *g, { /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - g->ops.mm.l2_flush(g, true); + if (g->ops.mm.l2_flush(g, true) != 0) { + nvgpu_err(g, "l2_flush failed"); + } nvgpu_mem_wr_n(g, target_mem, 0, local_golden_image->context, local_golden_image->size); diff --git a/drivers/gpu/nvgpu/common/ltc/ltc_gp10b.c b/drivers/gpu/nvgpu/common/ltc/ltc_gp10b.c index e678d198c..08e6f20d3 100644 --- a/drivers/gpu/nvgpu/common/ltc/ltc_gp10b.c +++ b/drivers/gpu/nvgpu/common/ltc/ltc_gp10b.c @@ -260,7 +260,9 @@ void gp10b_ltc_lts_isr(struct gk20a *g, unsigned int ltc, unsigned int slice) nvgpu_writel_check(g, ltc_ltc0_lts0_dstg_ecc_report_r() + offset, ecc_stats_reg_val); - g->ops.mm.l2_flush(g, true); + if (g->ops.mm.l2_flush(g, true) != 0) { + nvgpu_err(g, "l2_flush failed"); + } } if ((ltc_intr & ltc_ltcs_ltss_intr_ecc_ded_error_pending_f()) != 0U) { diff --git a/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c b/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c index 2b0d0b959..0e4d55e97 100644 --- a/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c +++ b/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c @@ -891,11 +891,15 @@ void gk20a_locked_gmmu_unmap(struct vm_gk20a *vm, } if (batch == NULL) { - gk20a_mm_l2_flush(g, true); + if (gk20a_mm_l2_flush(g, true) != 0) { + nvgpu_err(g, "gk20a_mm_l2_flush[1] failed"); + } g->ops.fb.tlb_invalidate(g, vm->pdb.mem); } else { if (!batch->gpu_l2_flushed) { - gk20a_mm_l2_flush(g, true); + if (gk20a_mm_l2_flush(g, true) != 0) { + nvgpu_err(g, "gk20a_mm_l2_flush[2] failed"); + } batch->gpu_l2_flushed = true; } batch->need_tlb_invalidate = true; diff --git a/drivers/gpu/nvgpu/common/mm/mm.c b/drivers/gpu/nvgpu/common/mm/mm.c index 6cd92809a..b90a90c07 100644 --- a/drivers/gpu/nvgpu/common/mm/mm.c +++ b/drivers/gpu/nvgpu/common/mm/mm.c @@ -116,12 +116,18 @@ u32 nvgpu_vm_get_pte_size(struct vm_gk20a *vm, u64 base, u64 size) int nvgpu_mm_suspend(struct gk20a *g) { + int err; + nvgpu_log_info(g, "MM suspend running..."); nvgpu_vidmem_thread_pause_sync(&g->mm); g->ops.mm.cbc_clean(g); - g->ops.mm.l2_flush(g, false); + err = g->ops.mm.l2_flush(g, false); + if (err != 0) { + nvgpu_err(g, "l2_flush failed"); + return err; + } if (g->ops.fb.disable_hub_intr != NULL) { g->ops.fb.disable_hub_intr(g); @@ -133,7 +139,7 @@ int nvgpu_mm_suspend(struct gk20a *g) nvgpu_log_info(g, "MM suspend done!"); - return 0; + return err; } u64 nvgpu_inst_block_addr(struct gk20a *g, struct nvgpu_mem *inst_block) diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index fb0897b87..395243b55 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -81,14 +81,17 @@ static void gr_gk20a_enable_elcg(struct gk20a *g); u32 gr_gk20a_get_ctx_id(struct gk20a *g, struct nvgpu_mem *ctx_mem) { - u32 ctx_id; + /* Initialize ctx_id to invalid value */ + u32 ctx_id = 0; /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - g->ops.mm.l2_flush(g, true); - - ctx_id = g->ops.gr.ctxsw_prog.get_main_image_ctx_id(g, ctx_mem); - nvgpu_log(g, gpu_dbg_fn | gpu_dbg_intr, "ctx_id: 0x%x", ctx_id); + if (g->ops.mm.l2_flush(g, true) != 0) { + nvgpu_err(g, "l2_flush failed"); + } else { + ctx_id = g->ops.gr.ctxsw_prog.get_main_image_ctx_id(g, ctx_mem); + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_intr, "ctx_id: 0x%x", ctx_id); + } return ctx_id; } @@ -1394,7 +1397,11 @@ restore_fe_go_idle: goto clean_up; } - g->ops.mm.l2_flush(g, true); + err = g->ops.mm.l2_flush(g, true); + if (err != 0) { + nvgpu_err(g, "l2_flush failed"); + goto clean_up; + } g->ops.gr.ctxsw_prog.set_zcull_mode_no_ctxsw(g, gr_mem); g->ops.gr.ctxsw_prog.set_zcull_ptr(g, gr_mem, 0); @@ -1462,7 +1469,11 @@ int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - g->ops.mm.l2_flush(g, true); + ret = g->ops.mm.l2_flush(g, true); + if (ret != 0) { + nvgpu_err(g, "l2_flush failed"); + goto out; + } g->ops.gr.ctxsw_prog.set_pm_smpc_mode(g, mem, enable_smpc_ctxsw); @@ -1546,7 +1557,11 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - g->ops.mm.l2_flush(g, true); + ret = g->ops.mm.l2_flush(g, true); + if (ret != 0) { + nvgpu_err(g, "l2_flush failed"); + return ret; + } if (mode != NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW) { /* Allocate buffer if necessary */ @@ -7404,7 +7419,11 @@ int __gr_gk20a_exec_ctx_ops(struct channel_gk20a *ch, goto cleanup; } - g->ops.mm.l2_flush(g, true); + err = g->ops.mm.l2_flush(g, true); + if (err != 0) { + nvgpu_err(g, "l2_flush failed"); + goto cleanup; + } /* write to appropriate place in context image, * first have to figure out where that really is */ diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index ce2ce77cb..7ca07fc6b 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -553,12 +553,13 @@ void gk20a_mm_l2_invalidate(struct gk20a *g) gk20a_idle_nosuspend(g); } -void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) +int gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) { struct mm_gk20a *mm = &g->mm; u32 data; struct nvgpu_timeout timeout; u32 retries = 2000; + int err = -ETIMEDOUT; nvgpu_log_fn(g, " "); @@ -592,6 +593,7 @@ void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) nvgpu_log_info(g, "l2_flush_dirty 0x%x", data); nvgpu_udelay(5); } else { + err = 0; break; } } while (nvgpu_timeout_expired_msg(&timeout, @@ -607,6 +609,8 @@ void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) hw_was_off: gk20a_idle_nosuspend(g); + + return err; } void gk20a_mm_cbc_clean(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 26290e79b..7440d2422 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h @@ -73,7 +73,7 @@ struct gk20a; struct channel_gk20a; int gk20a_mm_fb_flush(struct gk20a *g); -void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate); +int gk20a_mm_l2_flush(struct gk20a *g, bool invalidate); void gk20a_mm_cbc_clean(struct gk20a *g); void gk20a_mm_l2_invalidate(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gv11b/mm_gv11b.c b/drivers/gpu/nvgpu/gv11b/mm_gv11b.c index 21f5d5e51..3a69944a3 100644 --- a/drivers/gpu/nvgpu/gv11b/mm_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/mm_gv11b.c @@ -203,18 +203,38 @@ int gv11b_init_mm_setup_hw(struct gk20a *g) return err; } -void gv11b_mm_l2_flush(struct gk20a *g, bool invalidate) +int gv11b_mm_l2_flush(struct gk20a *g, bool invalidate) { + int err = 0; + nvgpu_log(g, gpu_dbg_fn, "gv11b_mm_l2_flush"); - g->ops.mm.fb_flush(g); - gk20a_mm_l2_flush(g, invalidate); - if (g->ops.bus.bar1_bind != NULL) { - g->ops.fb.tlb_invalidate(g, - g->mm.bar1.vm->pdb.mem); - } else { - g->ops.mm.fb_flush(g); + err = g->ops.mm.fb_flush(g); + if (err != 0) { + nvgpu_err(g, "mm.fb_flush()[1] failed err=%d", err); + return err; } + err = gk20a_mm_l2_flush(g, invalidate); + if (err != 0) { + nvgpu_err(g, "gk20a_mm_l2_flush failed"); + return err; + } + if (g->ops.bus.bar1_bind != NULL) { + err = g->ops.fb.tlb_invalidate(g, + g->mm.bar1.vm->pdb.mem); + if (err != 0) { + nvgpu_err(g, "fb.tlb_invalidate() failed err=%d", err); + return err; + } + } else { + err = g->ops.mm.fb_flush(g); + if (err != 0) { + nvgpu_err(g, "mm.fb_flush()[2] failed err=%d", err); + return err; + } + } + + return err; } /* diff --git a/drivers/gpu/nvgpu/gv11b/mm_gv11b.h b/drivers/gpu/nvgpu/gv11b/mm_gv11b.h index ba2470888..3b9ceb837 100644 --- a/drivers/gpu/nvgpu/gv11b/mm_gv11b.h +++ b/drivers/gpu/nvgpu/gv11b/mm_gv11b.h @@ -33,7 +33,7 @@ void gv11b_init_inst_block(struct nvgpu_mem *inst_block, struct vm_gk20a *vm, u32 big_page_size); bool gv11b_mm_mmu_fault_pending(struct gk20a *g); int gv11b_init_mm_setup_hw(struct gk20a *g); -void gv11b_mm_l2_flush(struct gk20a *g, bool invalidate); +int gv11b_mm_l2_flush(struct gk20a *g, bool invalidate); u64 gv11b_gpu_phys_addr(struct gk20a *g, struct nvgpu_gmmu_attrs *attrs, u64 phys); void gv11b_mm_fault_info_mem_destroy(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gv11b/subctx_gv11b.c b/drivers/gpu/nvgpu/gv11b/subctx_gv11b.c index 585543c7d..85096c441 100644 --- a/drivers/gpu/nvgpu/gv11b/subctx_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/subctx_gv11b.c @@ -102,6 +102,7 @@ int gv11b_update_subctx_header(struct channel_gk20a *c, u64 gpu_va) struct gk20a *g = c->g; struct tsg_gk20a *tsg; struct nvgpu_gr_ctx *gr_ctx; + int err = 0; tsg = tsg_gk20a_from_ch(c); if (tsg == NULL) { @@ -110,7 +111,11 @@ int gv11b_update_subctx_header(struct channel_gk20a *c, u64 gpu_va) gr_ctx = tsg->gr_ctx; - g->ops.mm.l2_flush(g, true); + err = g->ops.mm.l2_flush(g, true); + if (err != 0) { + nvgpu_err(g, "l2_flush failed"); + return err; + } /* set priv access map */ g->ops.gr.ctxsw_prog.set_priv_access_map_addr(g, ctxheader, @@ -129,7 +134,7 @@ int gv11b_update_subctx_header(struct channel_gk20a *c, u64 gpu_va) g->ops.gr.ctxsw_prog.set_type_per_veid_header(g, ctxheader); - return 0; + return err; } static void gv11b_subctx_commit_valid_mask(struct vm_gk20a *vm, diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 902f3c986..7977e36b0 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -1094,7 +1094,7 @@ struct gpu_ops { struct channel_gk20a *ch); int (*fb_flush)(struct gk20a *g); void (*l2_invalidate)(struct gk20a *g); - void (*l2_flush)(struct gk20a *g, bool invalidate); + int (*l2_flush)(struct gk20a *g, bool invalidate); void (*cbc_clean)(struct gk20a *g); void (*set_big_page_size)(struct gk20a *g, struct nvgpu_mem *mem, u32 size); diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index 2c0292a01..3b364c7d7 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -607,11 +607,17 @@ static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, (!args->l2_flush && args->l2_invalidate)) return -EINVAL; - if (args->l2_flush) - g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); + if (args->l2_flush) { + err = g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); + if (err != 0) { + nvgpu_err(g, "l2_flush failed"); + return err; + } + } - if (args->fb_flush) + if (args->fb_flush) { g->ops.mm.fb_flush(g); + } return err; } diff --git a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c index 78709ed64..cdc231cae 100644 --- a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c @@ -224,7 +224,7 @@ int vgpu_vm_bind_channel(struct vm_gk20a *vm, return err; } -static void vgpu_cache_maint(u64 handle, u8 op) +static int vgpu_cache_maint(u64 handle, u8 op) { struct tegra_vgpu_cmd_msg msg; struct tegra_vgpu_cache_maint_params *p = &msg.params.cache_maint; @@ -235,6 +235,7 @@ static void vgpu_cache_maint(u64 handle, u8 op) p->op = op; err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); WARN_ON(err || msg.ret); + return err; } int vgpu_mm_fb_flush(struct gk20a *g) @@ -242,8 +243,7 @@ int vgpu_mm_fb_flush(struct gk20a *g) nvgpu_log_fn(g, " "); - vgpu_cache_maint(vgpu_get_handle(g), TEGRA_VGPU_FB_FLUSH); - return 0; + return vgpu_cache_maint(vgpu_get_handle(g), TEGRA_VGPU_FB_FLUSH); } void vgpu_mm_l2_invalidate(struct gk20a *g) @@ -251,10 +251,10 @@ void vgpu_mm_l2_invalidate(struct gk20a *g) nvgpu_log_fn(g, " "); - vgpu_cache_maint(vgpu_get_handle(g), TEGRA_VGPU_L2_MAINT_INV); + (void) vgpu_cache_maint(vgpu_get_handle(g), TEGRA_VGPU_L2_MAINT_INV); } -void vgpu_mm_l2_flush(struct gk20a *g, bool invalidate) +int vgpu_mm_l2_flush(struct gk20a *g, bool invalidate) { u8 op; @@ -265,7 +265,7 @@ void vgpu_mm_l2_flush(struct gk20a *g, bool invalidate) else op = TEGRA_VGPU_L2_MAINT_FLUSH; - vgpu_cache_maint(vgpu_get_handle(g), op); + return vgpu_cache_maint(vgpu_get_handle(g), op); } int vgpu_mm_tlb_invalidate(struct gk20a *g, struct nvgpu_mem *pdb) diff --git a/drivers/gpu/nvgpu/vgpu/mm_vgpu.h b/drivers/gpu/nvgpu/vgpu/mm_vgpu.h index 491700fc0..1f4291db8 100644 --- a/drivers/gpu/nvgpu/vgpu/mm_vgpu.h +++ b/drivers/gpu/nvgpu/vgpu/mm_vgpu.h @@ -42,7 +42,7 @@ int vgpu_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch); int vgpu_mm_fb_flush(struct gk20a *g); void vgpu_mm_l2_invalidate(struct gk20a *g); -void vgpu_mm_l2_flush(struct gk20a *g, bool invalidate); +int vgpu_mm_l2_flush(struct gk20a *g, bool invalidate); int vgpu_mm_tlb_invalidate(struct gk20a *g, struct nvgpu_mem *pdb); void vgpu_mm_mmu_set_debug_mode(struct gk20a *g, bool enable); #endif