]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: IOCTL to disable timeouts
authorDeepak Nibade <dnibade@nvidia.com>
Thu, 20 Aug 2015 14:16:16 +0000 (19:46 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Thu, 10 Dec 2015 05:32:56 +0000 (21:32 -0800)
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
(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 <srasal@nvidia.com>
drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h
drivers/gpu/nvgpu/gk20a/gk20a.h
include/uapi/linux/nvgpu.h

index 486a03f50980f02dba011009b805310bd7b95100..645711bbf7adda8425de22f249390136669ee454 100644 (file)
@@ -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",
index 27084c0dbf6e94986138b8963453b50ff602b96f..fc1f2982297387adb3356107b296e4257290efd7 100644 (file)
@@ -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
index 709e0af2bee9bdf707e079e6b70cf368bb428b35..703977f0fe80ac84d1098ed44650d9bffa950406 100644 (file)
@@ -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 *);
 
index 5eaff06ae6171367c385fc89ca4f5647a59d1104..a10a9d5f17cbe3cf48f231e6899b8a8b83b96646 100644 (file)
@@ -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)