From 7466369a58308af9ca79e28a9ef66eb266233d42 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 20 May 2020 19:36:34 +0530 Subject: [PATCH] gpu: nvgpu: update hwpm/smpc ctxsw mode API to accept TSG Below APIs to update hwpm/smpc ctxsw mode take a channel pointer as a parameter. APIs then extract corresponding TSG from channel and perform various operations on context stored in TSG. g->ops.gr.update_smpc_ctxsw_mode() g->ops.gr.update_hwpm_ctxsw_mode() Update both above APIs to accept TSG pointer instead of a channel. This is a refactor work to support new profiler design where a profiler object is bound to TSG and keeps track of TSG only. Bug 2510974 Jira NVGPU-5360 Change-Id: Ia4cefda503d8420f2bd32d07c57534924f0f557a Signed-off-by: Deepak Nibade Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2366122 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c | 16 +-- drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.h | 4 +- drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c | 102 ++++-------------- drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.h | 5 +- drivers/gpu/nvgpu/include/nvgpu/gops_gr.h | 4 +- .../gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h | 2 +- drivers/gpu/nvgpu/os/linux/ioctl_dbg.c | 21 +++- 7 files changed, 53 insertions(+), 101 deletions(-) diff --git a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c index 398e2b420..dfaa95989 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c @@ -892,7 +892,7 @@ int vgpu_gr_set_sm_debug_mode(struct gk20a *g, } int vgpu_gr_update_smpc_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *ch, bool enable) + struct nvgpu_tsg *tsg, bool enable) { struct tegra_vgpu_cmd_msg msg; struct tegra_vgpu_channel_set_ctxsw_mode *p = &msg.params.set_ctxsw_mode; @@ -902,7 +902,7 @@ int vgpu_gr_update_smpc_ctxsw_mode(struct gk20a *g, msg.cmd = TEGRA_VGPU_CMD_CHANNEL_SET_SMPC_CTXSW_MODE; msg.handle = vgpu_get_handle(g); - p->handle = ch->virt_ctx; + p->tsg_id = tsg->tsgid; if (enable) { p->mode = TEGRA_VGPU_CTXSW_MODE_CTXSW; @@ -917,9 +917,8 @@ int vgpu_gr_update_smpc_ctxsw_mode(struct gk20a *g, } int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *ch, u64 gpu_va, u32 mode) + struct nvgpu_tsg *tsg, u64 gpu_va, u32 mode) { - struct nvgpu_tsg *tsg; struct nvgpu_gr_ctx *gr_ctx; struct tegra_vgpu_cmd_msg msg; struct tegra_vgpu_channel_set_ctxsw_mode *p = &msg.params.set_ctxsw_mode; @@ -927,11 +926,6 @@ int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, nvgpu_log_fn(g, " "); - tsg = nvgpu_tsg_from_ch(ch); - if (!tsg) { - return -EINVAL; - } - if (gpu_va) { nvgpu_err(g, "gpu_va suppose to be allocated by this function."); return -EINVAL; @@ -970,7 +964,7 @@ int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, if (mode != NVGPU_GR_CTX_HWPM_CTXSW_MODE_NO_CTXSW) { /* Allocate buffer if necessary */ - err = vgpu_gr_alloc_pm_ctx(g, tsg->gr_ctx, ch->vm); + err = vgpu_gr_alloc_pm_ctx(g, tsg->gr_ctx, tsg->vm); if (err != 0) { nvgpu_err(g, "failed to allocate pm ctxt buffer"); @@ -980,7 +974,7 @@ int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, msg.cmd = TEGRA_VGPU_CMD_CHANNEL_SET_HWPM_CTXSW_MODE; msg.handle = vgpu_get_handle(g); - p->handle = ch->virt_ctx; + p->tsg_id = tsg->tsgid; p->gpu_va = nvgpu_gr_ctx_get_pm_ctx_mem(gr_ctx)->gpu_va; err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); diff --git a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.h index 8beec3196..fba30199d 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.h +++ b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.h @@ -68,11 +68,11 @@ int vgpu_gr_query_zbc(struct gk20a *g, struct nvgpu_gr_zbc *zbc, struct nvgpu_gr_zbc_query_params *query_params); #endif int vgpu_gr_update_smpc_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *ch, bool enable); + struct nvgpu_tsg *tsg, bool enable); int vgpu_gr_set_sm_debug_mode(struct gk20a *g, struct nvgpu_channel *ch, u64 sms, bool enable); int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *ch, u64 gpu_va, u32 mode); + struct nvgpu_tsg *tsg, u64 gpu_va, u32 mode); int vgpu_gr_clear_sm_error_state(struct gk20a *g, struct nvgpu_channel *ch, u32 sm_id); int vgpu_gr_suspend_contexts(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c index bfb814c60..6b403b285 100644 --- a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c +++ b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.c @@ -54,72 +54,41 @@ #include int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *c, + struct nvgpu_tsg *tsg, bool enable_smpc_ctxsw) { - struct nvgpu_tsg *tsg; int ret; nvgpu_log_fn(g, " "); - tsg = nvgpu_tsg_from_ch(c); - if (tsg == NULL) { - return -EINVAL; - } + g->ops.tsg.disable(tsg); - ret = nvgpu_channel_disable_tsg(g, c); - if (ret != 0) { - /* ch might not be bound to tsg anymore */ - nvgpu_err(g, "failed to disable channel/TSG"); - return ret; - } - - ret = nvgpu_preempt_channel(g, c); + ret = g->ops.fifo.preempt_tsg(g, tsg); if (ret != 0) { + nvgpu_err(g, "failed to preempt TSG"); goto out; } ret = nvgpu_gr_ctx_set_smpc_mode(g, tsg->gr_ctx, enable_smpc_ctxsw); - if (ret != 0) { - goto out; - } - /* no error at this point */ - ret = nvgpu_channel_enable_tsg(g, c); - if (ret != 0) { - nvgpu_err(g, "failed to enable channel/TSG"); - } - return ret; out: - /* - * control reaches here if preempt failed or nvgpu_gr_ctx_set_smpc_mode - * failed. Propagate preempt failure err or err for - * nvgpu_gr_ctx_set_smpc_mode - */ - if (nvgpu_channel_enable_tsg(g, c) != 0) { - /* ch might not be bound to tsg anymore */ - nvgpu_err(g, "failed to enable channel/TSG"); - } + g->ops.tsg.enable(tsg); return ret; } int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *c, + struct nvgpu_tsg *tsg, u64 gpu_va, u32 mode) { - struct nvgpu_tsg *tsg; + struct nvgpu_channel *ch; struct nvgpu_gr_ctx *gr_ctx; bool skip_update = false; + int err; int ret; nvgpu_log_fn(g, " "); - tsg = nvgpu_tsg_from_ch(c); - if (tsg == NULL) { - return -EINVAL; - } - gr_ctx = tsg->gr_ctx; if (mode != NVGPU_GR_CTX_HWPM_CTXSW_MODE_NO_CTXSW) { @@ -128,7 +97,7 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, nvgpu_gr_hwpm_map_get_size(g->gr->hwpm_map)); ret = nvgpu_gr_ctx_alloc_pm_ctx(g, gr_ctx, - g->gr->gr_ctx_desc, c->vm, + g->gr->gr_ctx_desc, tsg->vm, gpu_va); if (ret != 0) { nvgpu_err(g, @@ -150,26 +119,18 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, return 0; } - ret = nvgpu_channel_disable_tsg(g, c); - if (ret != 0) { - /* ch might not be bound to tsg anymore */ - nvgpu_err(g, "failed to disable channel/TSG"); - return ret; - } + g->ops.tsg.disable(tsg); - ret = nvgpu_preempt_channel(g, c); + ret = g->ops.fifo.preempt_tsg(g, tsg); if (ret != 0) { - nvgpu_err(g, "failed to preempt channel/TSG"); + nvgpu_err(g, "failed to preempt TSG"); goto out; } - if (c->subctx != NULL) { - struct nvgpu_channel *ch; - int err; + nvgpu_rwsem_down_read(&tsg->ch_list_lock); - nvgpu_rwsem_down_read(&tsg->ch_list_lock); - - nvgpu_list_for_each_entry(ch, &tsg->ch_list, nvgpu_channel, ch_entry) { + nvgpu_list_for_each_entry(ch, &tsg->ch_list, nvgpu_channel, ch_entry) { + if (ch->subctx != NULL) { err = nvgpu_gr_ctx_set_hwpm_mode(g, gr_ctx, false); if (err != 0) { nvgpu_err(g, "chid: %d set_hwpm_mode failed", @@ -178,37 +139,16 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, continue; } nvgpu_gr_subctx_set_hwpm_mode(g, ch->subctx, gr_ctx); - } - - nvgpu_rwsem_up_read(&tsg->ch_list_lock); - - if (ret != 0) { - goto out; - } - } else { - ret = nvgpu_gr_ctx_set_hwpm_mode(g, gr_ctx, true); - if (ret != 0) { - goto out; + } else { + ret = nvgpu_gr_ctx_set_hwpm_mode(g, gr_ctx, true); + break; } } - /* no error at this point */ - ret = nvgpu_channel_enable_tsg(g, c); - if (ret != 0) { - nvgpu_err(g, "failed to enable channel/TSG"); - } - return ret; + + nvgpu_rwsem_up_read(&tsg->ch_list_lock); out: - /* - * control reaches here if preempt failed or - * set_hwpm_mode failed. Propagate preempt failure err or err for - * set_hwpm_mode - */ - - if (nvgpu_channel_enable_tsg(g, c) != 0) { - /* ch might not be bound to tsg anymore */ - nvgpu_err(g, "failed to enable channel/TSG"); - } + g->ops.tsg.enable(tsg); return ret; } diff --git a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.h b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.h index 2e135e4a9..607a6e030 100644 --- a/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.h +++ b/drivers/gpu/nvgpu/hal/gr/gr/gr_gk20a.h @@ -30,6 +30,7 @@ struct gk20a; struct nvgpu_channel; +struct nvgpu_tsg; struct nvgpu_warpstate; struct dbg_session_gk20a; struct nvgpu_dbg_reg_op; @@ -51,10 +52,10 @@ int gr_gk20a_get_pm_ctx_buffer_offsets(struct gk20a *g, u32 *offsets, u32 *offset_addrs, u32 *num_offsets); int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *c, + struct nvgpu_tsg *tsg, bool enable_smpc_ctxsw); int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, - struct nvgpu_channel *c, + struct nvgpu_tsg *tsg, u64 gpu_va, u32 mode); void gk20a_gr_resume_single_sm(struct gk20a *g, u32 gpc, u32 tpc, u32 sm); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops_gr.h b/drivers/gpu/nvgpu/include/nvgpu/gops_gr.h index 20370292f..3e94e990b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops_gr.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops_gr.h @@ -1101,10 +1101,10 @@ struct gops_gr { u32 *gpc_num, u32 *tpc_num); u32 (*get_egpc_base)(struct gk20a *g); int (*update_smpc_ctxsw_mode)(struct gk20a *g, - struct nvgpu_channel *c, + struct nvgpu_tsg *tsg, bool enable); int (*update_hwpm_ctxsw_mode)(struct gk20a *g, - struct nvgpu_channel *c, + struct nvgpu_tsg *tsg, u64 gpu_va, u32 mode); void (*init_hwpm_pmm_register)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h index 2ce129c35..71c19bdd6 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h @@ -372,7 +372,7 @@ enum { TEGRA_VGPU_ENABLE_SAMPLING, }; struct tegra_vgpu_channel_set_ctxsw_mode { - u64 handle; + u32 tsg_id; u64 gpu_va; u32 mode; }; diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index 809fb3ca4..4167c87ad 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -954,6 +954,7 @@ static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, int err; struct gk20a *g = dbg_s->g; struct nvgpu_channel *ch_gk20a; + struct nvgpu_tsg *tsg; nvgpu_log_fn(g, "%s smpc ctxsw mode = %d", g->name, args->mode); @@ -975,7 +976,14 @@ static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, goto clean_up; } - err = g->ops.gr.update_smpc_ctxsw_mode(g, ch_gk20a, + tsg = nvgpu_tsg_from_ch(ch_gk20a); + if (tsg == NULL) { + nvgpu_err(g, "channel not bound to TSG"); + err = -EINVAL; + goto clean_up; + } + + err = g->ops.gr.update_smpc_ctxsw_mode(g, tsg, args->mode == NVGPU_DBG_GPU_SMPC_CTXSW_MODE_CTXSW); if (err) { nvgpu_err(g, @@ -1015,6 +1023,7 @@ static int nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(struct dbg_session_gk20a *dbg_s, int err; struct gk20a *g = dbg_s->g; struct nvgpu_channel *ch_gk20a; + struct nvgpu_tsg *tsg; u32 mode = nvgpu_hwpm_ctxsw_mode_to_common_mode(args->mode); nvgpu_log_fn(g, "%s pm ctxsw mode = %d", g->name, args->mode); @@ -1050,7 +1059,15 @@ static int nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(struct dbg_session_gk20a *dbg_s, err = -ENOSYS; goto clean_up; } - err = g->ops.gr.update_hwpm_ctxsw_mode(g, ch_gk20a, 0, + + tsg = nvgpu_tsg_from_ch(ch_gk20a); + if (tsg == NULL) { + nvgpu_err(g, "channel not bound to TSG"); + err = -EINVAL; + goto clean_up; + } + + err = g->ops.gr.update_hwpm_ctxsw_mode(g, tsg, 0, mode); if (err)