gpu: nvgpu: IOCTL to disable timeouts

Add IOCTL NVGPU_DBG_GPU_IOCTL_TIMEOUT to support
disabling/re-enabling scheduler timeout from user space

If user space application is closed without re-enabling
the timeouts, kernel will restore the timeouts' state
while releasing the debug session

This is needed for debugging purpose

Bug 1514061

Change-Id: I32efb47ad09d793f3e7fd8f0aaa9720c8bc91272
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/788176
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Deepak Nibade
2015-08-20 19:46:16 +05:30
committed by Terje Bergstrom
parent 4b5c08f4c0
commit 8d279dbac1
4 changed files with 84 additions and 5 deletions

View File

@@ -91,6 +91,7 @@ static int gk20a_dbg_gpu_do_dev_open(struct inode *inode,
dbg_session->g = g; dbg_session->g = g;
dbg_session->is_profiler = is_profiler; dbg_session->is_profiler = is_profiler;
dbg_session->is_pg_disabled = false; dbg_session->is_pg_disabled = false;
dbg_session->is_timeout_disabled = false;
/* For vgpu, all power-gating features are currently disabled /* For vgpu, all power-gating features are currently disabled
* in the server. Set is_pg_disable to true to reflect this * in the server. Set is_pg_disable to true to reflect this
* on the client side. */ * on the client side. */
@@ -264,6 +265,46 @@ void gk20a_dbg_gpu_post_events(struct channel_gk20a *ch)
static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s,
__u32 powermode); __u32 powermode);
static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s,
int timeout_mode)
{
struct gk20a *g = dbg_s->g;
int err = 0;
gk20a_dbg(gpu_dbg_gpu_dbg, "Timeouts mode requested : %d",
timeout_mode);
switch (timeout_mode) {
case NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE:
if (dbg_s->is_timeout_disabled &&
--g->dbg_timeout_disabled_refcount == 0) {
g->timeouts_enabled = true;
}
dbg_s->is_timeout_disabled = false;
break;
case NVGPU_DBG_GPU_IOCTL_TIMEOUT_DISABLE:
if ((dbg_s->is_timeout_disabled == false) &&
(g->dbg_timeout_disabled_refcount++ == 0)) {
g->timeouts_enabled = false;
}
dbg_s->is_timeout_disabled = true;
break;
default:
gk20a_err(dev_from_gk20a(g),
"unrecognized dbg gpu timeout mode : 0x%x",
timeout_mode);
err = -EINVAL;
break;
}
gk20a_dbg(gpu_dbg_gpu_dbg, "Timeouts enabled : %s",
g->timeouts_enabled ? "Yes" : "No");
return err;
}
static int dbg_unbind_channel_gk20a(struct dbg_session_gk20a *dbg_s) static int dbg_unbind_channel_gk20a(struct dbg_session_gk20a *dbg_s)
{ {
struct channel_gk20a *ch_gk20a = dbg_s->ch; struct channel_gk20a *ch_gk20a = dbg_s->ch;
@@ -305,12 +346,13 @@ int gk20a_dbg_gpu_dev_release(struct inode *inode, struct file *filp)
if (dbg_s->ch) if (dbg_s->ch)
dbg_unbind_channel_gk20a(dbg_s); dbg_unbind_channel_gk20a(dbg_s);
/* Powergate enable is called here as possibility of dbg_session /* Powergate/Timeout enable is called here as possibility of dbg_session
* which called powergate disable ioctl, to be killed without calling * which called powergate/timeout disable ioctl, to be killed without
* powergate enable ioctl * calling powergate/timeout enable ioctl
*/ */
mutex_lock(&g->dbg_sessions_lock); mutex_lock(&g->dbg_sessions_lock);
dbg_set_powergate(dbg_s, NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE); dbg_set_powergate(dbg_s, NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE);
nvgpu_dbg_timeout_enable(dbg_s, NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE);
mutex_unlock(&g->dbg_sessions_lock); mutex_unlock(&g->dbg_sessions_lock);
kfree(dbg_s); kfree(dbg_s);
@@ -391,6 +433,22 @@ static int gk20a_dbg_pc_sampling(struct dbg_session_gk20a *dbg_s,
return g->ops.gr.update_pc_sampling ? return g->ops.gr.update_pc_sampling ?
g->ops.gr.update_pc_sampling(ch, args->enable) : -EINVAL; g->ops.gr.update_pc_sampling(ch, args->enable) : -EINVAL;
} }
static int nvgpu_dbg_gpu_ioctl_timeout(struct dbg_session_gk20a *dbg_s,
struct nvgpu_dbg_gpu_timeout_args *args)
{
int err;
struct gk20a *g = get_gk20a(dbg_s->pdev);
gk20a_dbg_fn("powergate mode = %d", args->enable);
mutex_lock(&g->dbg_sessions_lock);
err = nvgpu_dbg_timeout_enable(dbg_s, args->enable);
mutex_unlock(&g->dbg_sessions_lock);
return err;
}
long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
@@ -468,6 +526,11 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd,
(struct nvgpu_dbg_gpu_pc_sampling_args *)buf); (struct nvgpu_dbg_gpu_pc_sampling_args *)buf);
break; break;
case NVGPU_DBG_GPU_IOCTL_TIMEOUT:
err = nvgpu_dbg_gpu_ioctl_timeout(dbg_s,
(struct nvgpu_dbg_gpu_timeout_args *)buf);
break;
default: default:
gk20a_err(dev_from_gk20a(g), gk20a_err(dev_from_gk20a(g),
"unrecognized dbg gpu ioctl cmd: 0x%x", "unrecognized dbg gpu ioctl cmd: 0x%x",

View File

@@ -1,7 +1,7 @@
/* /*
* Tegra GK20A GPU Debugger Driver * Tegra GK20A GPU Debugger Driver
* *
* Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -53,6 +53,9 @@ struct dbg_session_gk20a {
/* power enabled or disabled */ /* power enabled or disabled */
bool is_pg_disabled; bool is_pg_disabled;
/* timeouts enabled or disabled */
bool is_timeout_disabled;
/* /*
* There can be different versions of the whitelists * There can be different versions of the whitelists
* between both global and per-context sets; as well * between both global and per-context sets; as well

View File

@@ -532,6 +532,7 @@ struct gk20a {
struct mutex dbg_sessions_lock; struct mutex dbg_sessions_lock;
int dbg_sessions; /* number attached */ int dbg_sessions; /* number attached */
int dbg_powergating_disabled_refcount; /*refcount for pg disable */ int dbg_powergating_disabled_refcount; /*refcount for pg disable */
int dbg_timeout_disabled_refcount; /*refcount for timeout disable */
void (*remove_support)(struct platform_device *); void (*remove_support)(struct platform_device *);

View File

@@ -547,8 +547,20 @@ struct nvgpu_dbg_gpu_pc_sampling_args {
#define NVGPU_DBG_GPU_IOCTL_PC_SAMPLING \ #define NVGPU_DBG_GPU_IOCTL_PC_SAMPLING \
_IOW(NVGPU_DBG_GPU_IOCTL_MAGIC, 9, struct nvgpu_dbg_gpu_pc_sampling_args) _IOW(NVGPU_DBG_GPU_IOCTL_MAGIC, 9, struct nvgpu_dbg_gpu_pc_sampling_args)
/* Enable/Disable timeouts */
#define NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE 1
#define NVGPU_DBG_GPU_IOCTL_TIMEOUT_DISABLE 0
struct nvgpu_dbg_gpu_timeout_args {
__u32 enable;
__u32 padding;
};
#define NVGPU_DBG_GPU_IOCTL_TIMEOUT \
_IOW(NVGPU_DBG_GPU_IOCTL_MAGIC, 10, struct nvgpu_dbg_gpu_timeout_args)
#define NVGPU_DBG_GPU_IOCTL_LAST \ #define NVGPU_DBG_GPU_IOCTL_LAST \
_IOC_NR(NVGPU_DBG_GPU_IOCTL_PC_SAMPLING) _IOC_NR(NVGPU_DBG_GPU_IOCTL_TIMEOUT)
#define NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE \ #define NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE \
sizeof(struct nvgpu_dbg_gpu_perfbuf_map_args) sizeof(struct nvgpu_dbg_gpu_perfbuf_map_args)