mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-25 02:52:51 +03:00
gpu: nvgpu: PG refcount check moved to a wrapper function.
Moved PG refcount checking to a wrapper function, this function manages the refcount and decides whether to call dbg_set_powergate function. Instead of checking the dbg_s->is_pg_disabled variable, code is checking g->dbg_powergating_disabled_refcount variable to know if powergate is disabled or not. Updating hwpm ctxsw mode without disabling powergate will result in priv errors. Bug 200410871 Bug 2109765 Change-Id: I33c9022cb04cd39249c78e72584dfe6afb7212d0 Signed-off-by: Vinod G <vinodg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1753550 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Richard Zhao <rizhao@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
52f1ab0372
commit
06ceff1240
@@ -169,6 +169,36 @@ int gk20a_dbg_gpu_clear_broadcast_stop_trigger(struct channel_gk20a *ch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvgpu_set_powergate_locked(struct dbg_session_gk20a *dbg_s,
|
||||
bool mode)
|
||||
{
|
||||
u32 err = 0U;
|
||||
struct gk20a *g = dbg_s->g;
|
||||
|
||||
if (dbg_s->is_pg_disabled != mode) {
|
||||
if (mode == false) {
|
||||
g->dbg_powergating_disabled_refcount--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow powergate disable or enable only if
|
||||
* the global pg disabled refcount is zero
|
||||
*/
|
||||
if (g->dbg_powergating_disabled_refcount == 0) {
|
||||
err = g->ops.dbg_session_ops.dbg_set_powergate(dbg_s,
|
||||
mode);
|
||||
}
|
||||
|
||||
if (mode) {
|
||||
g->dbg_powergating_disabled_refcount++;
|
||||
}
|
||||
|
||||
dbg_s->is_pg_disabled = mode;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -194,36 +224,28 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
|
||||
* clocking state changes allowed from mainline code (but they
|
||||
* should be saved).
|
||||
*/
|
||||
/* Allow powergate disable if the current dbg_session doesn't
|
||||
* call a powergate disable ioctl and the global
|
||||
* powergating_disabled_refcount is zero
|
||||
*/
|
||||
|
||||
if ((dbg_s->is_pg_disabled == false) &&
|
||||
(g->dbg_powergating_disabled_refcount++ == 0)) {
|
||||
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
|
||||
"module busy");
|
||||
err = gk20a_busy(g);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
|
||||
"module busy");
|
||||
err = gk20a_busy(g);
|
||||
if (err)
|
||||
return err;
|
||||
/*do elpg disable before clock gating */
|
||||
nvgpu_pmu_pg_global_enable(g, false);
|
||||
|
||||
/*do elpg disable before clock gating */
|
||||
nvgpu_pmu_pg_global_enable(g, false);
|
||||
if (g->ops.clock_gating.slcg_gr_load_gating_prod)
|
||||
g->ops.clock_gating.slcg_gr_load_gating_prod(g,
|
||||
false);
|
||||
if (g->ops.clock_gating.slcg_perf_load_gating_prod)
|
||||
g->ops.clock_gating.slcg_perf_load_gating_prod(g,
|
||||
false);
|
||||
if (g->ops.clock_gating.slcg_ltc_load_gating_prod)
|
||||
g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
|
||||
false);
|
||||
|
||||
if (g->ops.clock_gating.slcg_gr_load_gating_prod)
|
||||
g->ops.clock_gating.slcg_gr_load_gating_prod(g,
|
||||
false);
|
||||
if (g->ops.clock_gating.slcg_perf_load_gating_prod)
|
||||
g->ops.clock_gating.slcg_perf_load_gating_prod(g,
|
||||
false);
|
||||
if (g->ops.clock_gating.slcg_ltc_load_gating_prod)
|
||||
g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
|
||||
false);
|
||||
|
||||
gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN);
|
||||
gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
|
||||
}
|
||||
gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN);
|
||||
gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
|
||||
|
||||
dbg_s->is_pg_disabled = true;
|
||||
} else {
|
||||
@@ -231,42 +253,34 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
|
||||
/* release pending exceptions to fault/be handled as usual */
|
||||
/*TBD: ordering of these? */
|
||||
|
||||
/* Re-enabling powergate as no other sessions want
|
||||
* powergate disabled and the current dbg-sessions had
|
||||
* requested the powergate disable through ioctl
|
||||
*/
|
||||
if (dbg_s->is_pg_disabled &&
|
||||
--g->dbg_powergating_disabled_refcount == 0) {
|
||||
if (g->elcg_enabled)
|
||||
gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO);
|
||||
|
||||
if (g->elcg_enabled)
|
||||
gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO);
|
||||
if (g->blcg_enabled)
|
||||
gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO);
|
||||
|
||||
if (g->blcg_enabled)
|
||||
gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO);
|
||||
|
||||
if (g->slcg_enabled) {
|
||||
if (g->ops.clock_gating.
|
||||
slcg_ltc_load_gating_prod)
|
||||
g->ops.clock_gating.
|
||||
slcg_ltc_load_gating_prod(g,
|
||||
g->slcg_enabled);
|
||||
if (g->ops.clock_gating.
|
||||
slcg_perf_load_gating_prod)
|
||||
g->ops.clock_gating.
|
||||
slcg_perf_load_gating_prod(g,
|
||||
g->slcg_enabled);
|
||||
if (g->ops.clock_gating.
|
||||
slcg_gr_load_gating_prod)
|
||||
g->ops.clock_gating.
|
||||
slcg_gr_load_gating_prod(g,
|
||||
g->slcg_enabled);
|
||||
}
|
||||
nvgpu_pmu_pg_global_enable(g, true);
|
||||
|
||||
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
|
||||
"module idle");
|
||||
gk20a_idle(g);
|
||||
if (g->slcg_enabled) {
|
||||
if (g->ops.clock_gating.
|
||||
slcg_ltc_load_gating_prod)
|
||||
g->ops.clock_gating.
|
||||
slcg_ltc_load_gating_prod(g,
|
||||
g->slcg_enabled);
|
||||
if (g->ops.clock_gating.
|
||||
slcg_perf_load_gating_prod)
|
||||
g->ops.clock_gating.
|
||||
slcg_perf_load_gating_prod(g,
|
||||
g->slcg_enabled);
|
||||
if (g->ops.clock_gating.
|
||||
slcg_gr_load_gating_prod)
|
||||
g->ops.clock_gating.
|
||||
slcg_gr_load_gating_prod(g,
|
||||
g->slcg_enabled);
|
||||
}
|
||||
nvgpu_pmu_pg_global_enable(g, true);
|
||||
|
||||
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
|
||||
"module idle");
|
||||
gk20a_idle(g);
|
||||
|
||||
dbg_s->is_pg_disabled = false;
|
||||
}
|
||||
|
||||
@@ -133,4 +133,6 @@ int gk20a_perfbuf_enable_locked(struct gk20a *g, u64 offset, u32 size);
|
||||
int gk20a_perfbuf_disable_locked(struct gk20a *g);
|
||||
|
||||
void nvgpu_dbg_session_post_event(struct dbg_session_gk20a *dbg_s);
|
||||
u32 nvgpu_set_powergate_locked(struct dbg_session_gk20a *dbg_s,
|
||||
bool mode);
|
||||
#endif /* DBG_GPU_GK20A_H */
|
||||
|
||||
@@ -181,7 +181,9 @@ int gk20a_dbg_gpu_dev_release(struct inode *inode, struct file *filp)
|
||||
* calling powergate/timeout enable ioctl
|
||||
*/
|
||||
nvgpu_mutex_acquire(&g->dbg_sessions_lock);
|
||||
g->ops.dbg_session_ops.dbg_set_powergate(dbg_s, false);
|
||||
if (dbg_s->is_pg_disabled) {
|
||||
nvgpu_set_powergate_locked(dbg_s, false);
|
||||
}
|
||||
nvgpu_dbg_timeout_enable(dbg_s, NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE);
|
||||
|
||||
/* If this session owned the perf buffer, release it */
|
||||
@@ -867,9 +869,10 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s,
|
||||
/* In the virtual case, the server will handle
|
||||
* disabling/enabling powergating when processing reg ops
|
||||
*/
|
||||
powergate_err = g->ops.dbg_session_ops.dbg_set_powergate(dbg_s,
|
||||
true);
|
||||
is_pg_disabled = true;
|
||||
powergate_err = nvgpu_set_powergate_locked(dbg_s, true);
|
||||
if (!powergate_err) {
|
||||
is_pg_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!powergate_err) {
|
||||
@@ -938,9 +941,8 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s,
|
||||
|
||||
/* enable powergate, if previously disabled */
|
||||
if (is_pg_disabled) {
|
||||
powergate_err =
|
||||
g->ops.dbg_session_ops.dbg_set_powergate(dbg_s,
|
||||
false);
|
||||
powergate_err = nvgpu_set_powergate_locked(dbg_s,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,14 +966,16 @@ static int nvgpu_ioctl_powergate_gk20a(struct dbg_session_gk20a *dbg_s,
|
||||
g->name, args->mode);
|
||||
|
||||
nvgpu_mutex_acquire(&g->dbg_sessions_lock);
|
||||
if (args->mode == NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE) {
|
||||
err = g->ops.dbg_session_ops.dbg_set_powergate(dbg_s, true);
|
||||
} else if (args->mode == NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE) {
|
||||
err = g->ops.dbg_session_ops.dbg_set_powergate(dbg_s, false);
|
||||
} else {
|
||||
if ((args->mode != NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE) &&
|
||||
(args->mode != NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE)) {
|
||||
nvgpu_err(g, "invalid powergate mode");
|
||||
err = -EINVAL;
|
||||
goto pg_err_end;
|
||||
}
|
||||
|
||||
err = nvgpu_set_powergate_locked(dbg_s,
|
||||
args->mode == NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE);
|
||||
pg_err_end:
|
||||
nvgpu_mutex_release(&g->dbg_sessions_lock);
|
||||
return err;
|
||||
}
|
||||
@@ -1053,7 +1057,7 @@ static int nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(struct dbg_session_gk20a *dbg_s,
|
||||
err = -EINVAL;
|
||||
goto clean_up;
|
||||
}
|
||||
if (!dbg_s->is_pg_disabled) {
|
||||
if (g->dbg_powergating_disabled_refcount == 0) {
|
||||
nvgpu_err(g, "powergate is not disabled");
|
||||
err = -ENOSYS;
|
||||
goto clean_up;
|
||||
|
||||
Reference in New Issue
Block a user