From d538737ba18bfcc5f062491b5e6ae9212d7ebe68 Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 14 Aug 2021 07:58:39 +0000 Subject: [PATCH] gpu: nvgpu: Add ELPG_MS protected call for L2 flush - if L2 flush is done when ELPG_MS feature is engaged then it can cause some of the signals to go non-idle. This can cause idle snap in ELPG_MS. - To avoid the idle snap, add elpg_ms protected call before L2 flush operation Bug 200763448 Change-Id: I651875bc051c3b7d26d2bb0b593083512a5765b2 Signed-off-by: Divya Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2599459 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Mahantesh Kumbar Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/common/gr/ctx.c | 10 ++++++---- drivers/gpu/nvgpu/common/gr/global_ctx.c | 4 +++- drivers/gpu/nvgpu/common/gr/subctx.c | 3 ++- drivers/gpu/nvgpu/common/mm/gmmu/page_table.c | 6 ++++-- drivers/gpu/nvgpu/common/mm/mm.c | 4 +++- drivers/gpu/nvgpu/common/mm/vm_remap.c | 3 ++- drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c | 4 +++- drivers/gpu/nvgpu/hal/ltc/intr/ltc_intr_gp10b_fusa.c | 6 ++++-- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 5 +++-- drivers/gpu/nvgpu/os/linux/ioctl_dbg.c | 2 +- drivers/gpu/nvgpu/os/linux/vm_remap.c | 9 ++++++++- 11 files changed, 39 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/ctx.c b/drivers/gpu/nvgpu/common/gr/ctx.c index 5a7bc8d92..a50601566 100644 --- a/drivers/gpu/nvgpu/common/gr/ctx.c +++ b/drivers/gpu/nvgpu/common/gr/ctx.c @@ -29,6 +29,7 @@ #include #include +#include #include "common/gr/ctx_priv.h" static void nvgpu_gr_ctx_unmap_global_ctx_buffers(struct gk20a *g, @@ -738,7 +739,7 @@ int nvgpu_gr_ctx_init_zcull(struct gk20a *g, struct nvgpu_gr_ctx *gr_ctx) nvgpu_log(g, gpu_dbg_gr, " "); - err = g->ops.mm.cache.l2_flush(g, true); + err = nvgpu_pg_elpg_ms_protected_call(g, g->ops.mm.cache.l2_flush(g, true)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); return err; @@ -1046,7 +1047,8 @@ u32 nvgpu_gr_ctx_get_ctx_id(struct gk20a *g, struct nvgpu_gr_ctx *gr_ctx) if (!gr_ctx->ctx_id_valid) { /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - if (g->ops.mm.cache.l2_flush(g, true) != 0) { + if (nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, true)) != 0) { nvgpu_err(g, "l2_flush failed"); } @@ -1097,7 +1099,7 @@ int nvgpu_gr_ctx_set_smpc_mode(struct gk20a *g, struct nvgpu_gr_ctx *gr_ctx, /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - err = g->ops.mm.cache.l2_flush(g, true); + err = nvgpu_pg_elpg_ms_protected_call(g, g->ops.mm.cache.l2_flush(g, true)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); return err; @@ -1174,7 +1176,7 @@ int nvgpu_gr_ctx_set_hwpm_mode(struct gk20a *g, struct nvgpu_gr_ctx *gr_ctx, /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - err = g->ops.mm.cache.l2_flush(g, true); + err = nvgpu_pg_elpg_ms_protected_call(g, g->ops.mm.cache.l2_flush(g, true)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); return err; diff --git a/drivers/gpu/nvgpu/common/gr/global_ctx.c b/drivers/gpu/nvgpu/common/gr/global_ctx.c index d2f04e3ad..0dda4b557 100644 --- a/drivers/gpu/nvgpu/common/gr/global_ctx.c +++ b/drivers/gpu/nvgpu/common/gr/global_ctx.c @@ -32,6 +32,7 @@ #endif #include +#include #include "global_ctx_priv.h" @@ -453,7 +454,8 @@ 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. */ - if (g->ops.mm.cache.l2_flush(g, true) != 0) { + if (nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, true)) != 0) { nvgpu_err(g, "l2_flush failed"); } diff --git a/drivers/gpu/nvgpu/common/gr/subctx.c b/drivers/gpu/nvgpu/common/gr/subctx.c index 0b5157ee8..da2345fff 100644 --- a/drivers/gpu/nvgpu/common/gr/subctx.c +++ b/drivers/gpu/nvgpu/common/gr/subctx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "common/gr/subctx_priv.h" @@ -85,7 +86,7 @@ void nvgpu_gr_subctx_load_ctx_header(struct gk20a *g, struct nvgpu_mem *ctxheader = &subctx->ctx_header; int err = 0; - err = g->ops.mm.cache.l2_flush(g, true); + err = nvgpu_pg_elpg_ms_protected_call(g, g->ops.mm.cache.l2_flush(g, true)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); } diff --git a/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c b/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c index 1f27c2600..33eb1a02f 100644 --- a/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c +++ b/drivers/gpu/nvgpu/common/mm/gmmu/page_table.c @@ -873,7 +873,8 @@ static int nvgpu_gmmu_cache_maint_unmap(struct gk20a *g, struct vm_gk20a *vm, int err = 0; if (batch == NULL) { - if (g->ops.mm.cache.l2_flush(g, true) != 0) { + if ((nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, true))) != 0) { nvgpu_err(g, "gk20a_mm_l2_flush[1] failed"); } err = g->ops.fb.tlb_invalidate(g, vm->pdb.mem); @@ -882,7 +883,8 @@ static int nvgpu_gmmu_cache_maint_unmap(struct gk20a *g, struct vm_gk20a *vm, } } else { if (!batch->gpu_l2_flushed) { - if (g->ops.mm.cache.l2_flush(g, true) != 0) { + if ((nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, true))) != 0) { nvgpu_err(g, "gk20a_mm_l2_flush[2] failed"); } batch->gpu_l2_flushed = true; diff --git a/drivers/gpu/nvgpu/common/mm/mm.c b/drivers/gpu/nvgpu/common/mm/mm.c index 4b225d2f9..2d5365639 100644 --- a/drivers/gpu/nvgpu/common/mm/mm.c +++ b/drivers/gpu/nvgpu/common/mm/mm.c @@ -36,6 +36,7 @@ #include #include #include +#include int nvgpu_mm_suspend(struct gk20a *g) { @@ -50,7 +51,8 @@ int nvgpu_mm_suspend(struct gk20a *g) #ifdef CONFIG_NVGPU_COMPRESSION g->ops.mm.cache.cbc_clean(g); #endif - err = g->ops.mm.cache.l2_flush(g, false); + err = nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, false)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); return err; diff --git a/drivers/gpu/nvgpu/common/mm/vm_remap.c b/drivers/gpu/nvgpu/common/mm/vm_remap.c index 92fffb368..8807f1a63 100644 --- a/drivers/gpu/nvgpu/common/mm/vm_remap.c +++ b/drivers/gpu/nvgpu/common/mm/vm_remap.c @@ -26,6 +26,7 @@ #include #include #include +#include /* * Return page size index of page size for VM areas that can be used with @@ -89,7 +90,7 @@ static void nvgpu_vm_remap_mpool_release(struct nvgpu_ref *ref) /* L2 must be flushed before we destroy any SMMU mappings. */ if (*mpool->l2_flushed == false) { - (void) g->ops.mm.cache.l2_flush(g, true); + (void) nvgpu_pg_elpg_ms_protected_call(g, g->ops.mm.cache.l2_flush(g, true)); *mpool->l2_flushed = true; } diff --git a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c index 193ac76ca..4a53ac3f0 100644 --- a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c +++ b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "gr_gk20a.h" #include "gr_pri_gk20a.h" @@ -1480,7 +1481,8 @@ static int gr_exec_ctx_ops(struct nvgpu_tsg *tsg, nvgpu_gr_ctx_patch_write_begin(g, gr_ctx, false); - err = g->ops.mm.cache.l2_flush(g, true); + err = nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, true)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); goto cleanup; diff --git a/drivers/gpu/nvgpu/hal/ltc/intr/ltc_intr_gp10b_fusa.c b/drivers/gpu/nvgpu/hal/ltc/intr/ltc_intr_gp10b_fusa.c index 16f5b6d5e..329b0b261 100644 --- a/drivers/gpu/nvgpu/hal/ltc/intr/ltc_intr_gp10b_fusa.c +++ b/drivers/gpu/nvgpu/hal/ltc/intr/ltc_intr_gp10b_fusa.c @@ -1,7 +1,7 @@ /* * GP10B L2 INTR * - * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -67,7 +68,8 @@ void gp10b_ltc_intr_handle_lts_interrupts(struct gk20a *g, u32 ltc, u32 slice) nvgpu_safe_add_u32( ltc_ltc0_lts0_dstg_ecc_report_r(), offset), ecc_stats_reg_val); - if (g->ops.mm.cache.l2_flush(g, true) != 0) { + if (nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, true)) != 0) { nvgpu_err(g, "l2_flush failed"); } } diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index d053f32fc..9a74007a5 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -781,8 +781,9 @@ static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, } if (args->l2_flush) { - err = g->ops.mm.cache.l2_flush(g, args->l2_invalidate ? - true : false); + err = nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, args->l2_invalidate ? + true : false)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); goto out; diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index ed46ccbd0..61669f3eb 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -1952,7 +1952,7 @@ static int nvgpu_dbg_gpu_ioctl_get_gr_context(struct dbg_session_gk20a *dbg_s, /* Channel gr_ctx buffer is gpu cacheable. Flush and invalidate before cpu update. */ - err = g->ops.mm.cache.l2_flush(g, true); + err = nvgpu_pg_elpg_ms_protected_call(g, g->ops.mm.cache.l2_flush(g, true)); if (err != 0) { nvgpu_err(g, "l2_flush failed"); goto done; diff --git a/drivers/gpu/nvgpu/os/linux/vm_remap.c b/drivers/gpu/nvgpu/os/linux/vm_remap.c index 5cabc22e5..6e3ff1f0b 100644 --- a/drivers/gpu/nvgpu/os/linux/vm_remap.c +++ b/drivers/gpu/nvgpu/os/linux/vm_remap.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "os_linux.h" #include "dmabuf_priv.h" @@ -127,6 +128,7 @@ void nvgpu_vm_remap_os_buf_put(struct vm_gk20a *vm, struct gk20a *g = gk20a_from_vm(vm); struct device *dev = dev_from_gk20a(g); struct gk20a_comptags comptags; + int err = 0; nvgpu_mm_unpin(dev, remap_os_buf->os_priv.dmabuf, remap_os_buf->os_priv.attachment, remap_os_buf->os_priv.sgt); @@ -139,7 +141,12 @@ void nvgpu_vm_remap_os_buf_put(struct vm_gk20a *vm, */ if (comptags.offset != 0) { g->ops.cbc.ctrl(g, nvgpu_cbc_op_clean, 0, 0); - g->ops.mm.cache.l2_flush(g, true); + err = nvgpu_pg_elpg_ms_protected_call(g, + g->ops.mm.cache.l2_flush(g, true)); + if (err != 0) { + nvgpu_err(g, "l2 flush failed"); + return; + } } nvgpu_sgt_free(g, remap_os_buf->nv_sgt);