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 <dnibade@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2366122
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Deepak Nibade
2020-05-20 19:36:34 +05:30
committed by Alex Waterman
parent 59230fe64a
commit 7466369a58
7 changed files with 53 additions and 101 deletions

View File

@@ -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));

View File

@@ -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,

View File

@@ -54,72 +54,41 @@
#include <nvgpu/hw/gk20a/hw_gr_gk20a.h>
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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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)