From 2724189a8d136f6ce570f95c216107fe5d6d5542 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Thu, 20 Aug 2015 19:46:16 +0530 Subject: [PATCH] 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 Reviewed-on: http://git-master/r/788176 (cherry picked from commit e338eb25e9177ca25a2035f10b93e378ac8bbf16) Reviewed-on: http://git-master/r/841468 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Shridhar Rasal --- drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 69 +++++++++++++++++++++++-- drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h | 5 +- drivers/gpu/nvgpu/gk20a/gk20a.h | 1 + include/uapi/linux/nvgpu.h | 14 ++++- 4 files changed, 84 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 486a03f5098..645711bbf7a 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c @@ -91,6 +91,7 @@ static int gk20a_dbg_gpu_do_dev_open(struct inode *inode, dbg_session->g = g; dbg_session->is_profiler = is_profiler; dbg_session->is_pg_disabled = false; + dbg_session->is_timeout_disabled = false; /* For vgpu, all power-gating features are currently disabled * in the server. Set is_pg_disable to true to reflect this * 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, __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) { 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) dbg_unbind_channel_gk20a(dbg_s); - /* Powergate enable is called here as possibility of dbg_session - * which called powergate disable ioctl, to be killed without calling - * powergate enable ioctl + /* Powergate/Timeout enable is called here as possibility of dbg_session + * which called powergate/timeout disable ioctl, to be killed without + * calling powergate/timeout enable ioctl */ mutex_lock(&g->dbg_sessions_lock); 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); 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 ? 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, 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); break; + case NVGPU_DBG_GPU_IOCTL_TIMEOUT: + err = nvgpu_dbg_gpu_ioctl_timeout(dbg_s, + (struct nvgpu_dbg_gpu_timeout_args *)buf); + break; + default: gk20a_err(dev_from_gk20a(g), "unrecognized dbg gpu ioctl cmd: 0x%x", diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h index 27084c0dbf6..fc1f2982297 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h @@ -1,7 +1,7 @@ /* * 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 * under the terms and conditions of the GNU General Public License, @@ -53,6 +53,9 @@ struct dbg_session_gk20a { /* power enabled or disabled */ bool is_pg_disabled; + /* timeouts enabled or disabled */ + bool is_timeout_disabled; + /* * There can be different versions of the whitelists * between both global and per-context sets; as well diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 709e0af2bee..703977f0fe8 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -470,6 +470,7 @@ struct gk20a { struct mutex dbg_sessions_lock; int dbg_sessions; /* number attached */ int dbg_powergating_disabled_refcount; /*refcount for pg disable */ + int dbg_timeout_disabled_refcount; /*refcount for timeout disable */ void (*remove_support)(struct platform_device *); diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h index 5eaff06ae61..a10a9d5f17c 100644 --- a/include/uapi/linux/nvgpu.h +++ b/include/uapi/linux/nvgpu.h @@ -536,8 +536,20 @@ struct nvgpu_dbg_gpu_pc_sampling_args { #define NVGPU_DBG_GPU_IOCTL_PC_SAMPLING \ _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 \ - _IOC_NR(NVGPU_DBG_GPU_IOCTL_PC_SAMPLING) + _IOC_NR(NVGPU_DBG_GPU_IOCTL_TIMEOUT) #define NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE \ sizeof(struct nvgpu_dbg_gpu_perfbuf_map_args) -- 2.39.2