From 8edf86ef1849fe0e05f7df987468102ee898cf3a Mon Sep 17 00:00:00 2001 From: Vaibhav Kachore Date: Mon, 25 Mar 2019 16:43:39 +0530 Subject: [PATCH] gpu: nvgpu: Enabling/disabling FECS trace support - To enable FECS trace support, nvgpu should set the MSB of the read pointer (MAILBOX1). - The ucode will check if the feature is enabled/disabled before writing a record into the circular buffer. If the feature is disabled, it will not write the record. - If the feature is enabled and the buffer is not allocated, HW will throw a page fault error. Bug 2459186 Change-Id: I71daf6fdb1bb67974f6e51e091f868cb08d3b0bf Signed-off-by: Vaibhav Kachore Reviewed-on: https://git-master.nvidia.com/r/2111028 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/fecs_trace.c | 61 +++++++++++++++++++ drivers/gpu/nvgpu/hal/init/hal_gm20b.c | 1 + drivers/gpu/nvgpu/hal/init/hal_gp10b.c | 1 + drivers/gpu/nvgpu/hal/init/hal_gv100.c | 1 + drivers/gpu/nvgpu/hal/init/hal_gv11b.c | 1 + drivers/gpu/nvgpu/hal/init/hal_tu104.c | 1 + drivers/gpu/nvgpu/include/nvgpu/enabled.h | 1 + .../gpu/nvgpu/include/nvgpu/gr/fecs_trace.h | 1 + 8 files changed, 68 insertions(+) diff --git a/drivers/gpu/nvgpu/common/gr/fecs_trace.c b/drivers/gpu/nvgpu/common/gr/fecs_trace.c index 03944b53c..43f5b8d88 100644 --- a/drivers/gpu/nvgpu/common/gr/fecs_trace.c +++ b/drivers/gpu/nvgpu/common/gr/fecs_trace.c @@ -272,8 +272,31 @@ int nvgpu_gr_fecs_trace_enable(struct gk20a *g) g->ops.gr.fecs_trace.flush(g); write = g->ops.gr.fecs_trace.get_write_index(g); + + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * For enabling FECS trace support, MAILBOX1's MSB + * (Bit 31:31) should be set to 1. Bits 30:0 represents + * actual pointer value. + */ + write = write | + (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT)); + } + g->ops.gr.fecs_trace.set_read_index(g, write); + /* + * FECS ucode does a priv holdoff around the assertion of + * context reset. So, pri transactions (e.g. mailbox1 register + * write) might fail due to this. Hence, do write with ack + * i.e. write and read it back to make sure write happened for + * mailbox1. + */ + while (g->ops.gr.fecs_trace.get_read_index(g) != write) { + nvgpu_log(g, gpu_dbg_ctxsw, "mailbox1 update failed"); + g->ops.gr.fecs_trace.set_read_index(g, write); + } + err = nvgpu_thread_create(&trace->poll_task, g, nvgpu_gr_fecs_trace_periodic_polling, __func__); if (err != 0) { @@ -290,6 +313,7 @@ done: int nvgpu_gr_fecs_trace_disable(struct gk20a *g) { struct nvgpu_gr_fecs_trace *trace = g->fecs_trace; + int read = 0; if (trace == NULL) { return -EINVAL; @@ -298,6 +322,29 @@ int nvgpu_gr_fecs_trace_disable(struct gk20a *g) nvgpu_mutex_acquire(&trace->enable_lock); trace->enable_count--; if (trace->enable_count == 0U) { + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * For disabling FECS trace support, MAILBOX1's MSB + * (Bit 31:31) should be set to 0. + */ + read = g->ops.gr.fecs_trace.get_read_index(g) & + (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT))); + + g->ops.gr.fecs_trace.set_read_index(g, read); + + /* + * FECS ucode does a priv holdoff around the assertion + * of context reset. So, pri transactions (e.g. + * mailbox1 register write) might fail due to this. + * Hence, do write with ack i.e. write and read it back + * to make sure write happened for mailbox1. + */ + while (g->ops.gr.fecs_trace.get_read_index(g) != read) { + nvgpu_log(g, gpu_dbg_ctxsw, + "mailbox1 update failed"); + g->ops.gr.fecs_trace.set_read_index(g, read); + } + } nvgpu_thread_stop(&trace->poll_task); } nvgpu_mutex_release(&trace->enable_lock); @@ -483,6 +530,11 @@ int nvgpu_gr_fecs_trace_poll(struct gk20a *g) /* Ensure all FECS writes have made it to SYSMEM */ g->ops.mm.cache.fb_flush(g); + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* Bits 30:0 of MAILBOX1 represents actual read pointer value */ + read = read & (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT))); + } + while (read != write) { cnt = nvgpu_gr_fecs_trace_ring_read(g, read, &vm_update_mask); if (cnt <= 0) { @@ -493,6 +545,15 @@ int nvgpu_gr_fecs_trace_poll(struct gk20a *g) read = (read + 1) & (GK20A_FECS_TRACE_NUM_RECORDS - 1); } + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * In the next step, read pointer is going to be updated. + * So, MSB of read pointer should be set back to 1. This will + * keep FECS trace enabled. + */ + read = read | (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT)); + } + /* ensure FECS records has been updated before incrementing read index */ nvgpu_wmb(); g->ops.gr.fecs_trace.set_read_index(g, read); diff --git a/drivers/gpu/nvgpu/hal/init/hal_gm20b.c b/drivers/gpu/nvgpu/hal/init/hal_gm20b.c index de55c203b..1f527c7b7 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gm20b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gm20b.c @@ -1055,6 +1055,7 @@ int gm20b_init_hal(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP, true); nvgpu_set_enabled(g, NVGPU_PMU_PSTATE, false); nvgpu_set_enabled(g, NVGPU_FECS_TRACE_VA, false); + nvgpu_set_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL, false); /* Read fuses to check if gpu needs to boot in secure/non-secure mode */ if (gops->fuse.check_priv_security(g) != 0) { diff --git a/drivers/gpu/nvgpu/hal/init/hal_gp10b.c b/drivers/gpu/nvgpu/hal/init/hal_gp10b.c index ea7c7d4c2..bc0979f74 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gp10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gp10b.c @@ -1122,6 +1122,7 @@ int gp10b_init_hal(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP, true); nvgpu_set_enabled(g, NVGPU_PMU_PSTATE, false); nvgpu_set_enabled(g, NVGPU_FECS_TRACE_VA, false); + nvgpu_set_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL, false); nvgpu_pramin_ops_init(g); diff --git a/drivers/gpu/nvgpu/hal/init/hal_gv100.c b/drivers/gpu/nvgpu/hal/init/hal_gv100.c index 947358fc4..85773ef56 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gv100.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gv100.c @@ -1398,6 +1398,7 @@ int gv100_init_hal(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, false); nvgpu_set_enabled(g, NVGPU_SUPPORT_MULTIPLE_WPR, false); nvgpu_set_enabled(g, NVGPU_FECS_TRACE_VA, true); + nvgpu_set_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL, false); nvgpu_set_enabled(g, NVGPU_SUPPORT_PMU_RTOS_FBQ, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_ZBC_STENCIL, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_PREEMPTION_GFXP, true); diff --git a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c index 36de185b7..8252d8f6f 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c @@ -1297,6 +1297,7 @@ int gv11b_init_hal(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, false); nvgpu_set_enabled(g, NVGPU_FECS_TRACE_VA, true); + nvgpu_set_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_MULTIPLE_WPR, false); nvgpu_set_enabled(g, NVGPU_SUPPORT_ZBC_STENCIL, true); diff --git a/drivers/gpu/nvgpu/hal/init/hal_tu104.c b/drivers/gpu/nvgpu/hal/init/hal_tu104.c index 0ac16cddf..4f28596e8 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_tu104.c +++ b/drivers/gpu/nvgpu/hal/init/hal_tu104.c @@ -1446,6 +1446,7 @@ int tu104_init_hal(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, false); nvgpu_set_enabled(g, NVGPU_SUPPORT_MULTIPLE_WPR, true); nvgpu_set_enabled(g, NVGPU_FECS_TRACE_VA, true); + nvgpu_set_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_SEC2_RTOS, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_PMU_RTOS_FBQ, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_ZBC_STENCIL, true); diff --git a/drivers/gpu/nvgpu/include/nvgpu/enabled.h b/drivers/gpu/nvgpu/include/nvgpu/enabled.h index 82c39513d..c0e34ee61 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/enabled.h +++ b/drivers/gpu/nvgpu/include/nvgpu/enabled.h @@ -37,6 +37,7 @@ struct gk20a; #define NVGPU_FECS_TRACE_VA 4 #define NVGPU_CAN_RAILGATE 5 #define NVGPU_KERNEL_IS_DYING 6 +#define NVGPU_FECS_TRACE_FEATURE_CONTROL 7 /* * ECC flags diff --git a/drivers/gpu/nvgpu/include/nvgpu/gr/fecs_trace.h b/drivers/gpu/nvgpu/include/nvgpu/gr/fecs_trace.h index 80ed0b32c..f22371dd6 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gr/fecs_trace.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gr/fecs_trace.h @@ -55,6 +55,7 @@ ((p)->tag_bits[(n) / 64] & (1 << ((n) & 63))) #define NVGPU_GPU_CTXSW_FILTER_SIZE (NVGPU_GPU_CTXSW_TAG_LAST + 1) +#define NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT 31 struct gk20a; struct nvgpu_mem;