mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-25 11:04:51 +03:00
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:
committed by
Alex Waterman
parent
59230fe64a
commit
7466369a58
@@ -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));
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user