From 982fcfa737be54fd0ab16792faf97a2741e34907 Mon Sep 17 00:00:00 2001 From: Seema Khowala Date: Mon, 30 Oct 2017 14:15:51 -0700 Subject: gpu: nvgpu: Add timeouts_disabled_refcount for enabling timeout -timeouts will be enabled only when timeouts_disabled_refcount will reach 0 -timeouts_enabled debugfs will change from u32 type to file type to avoid race enabling/disabling timeout from debugfs and ioctl -unify setting timeouts_enabled from debugfs and ioctl Bug 1982434 Change-Id: I54bab778f1ae533872146dfb8d80deafd2a685c7 Signed-off-by: Seema Khowala Reviewed-on: https://git-master.nvidia.com/r/1588690 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/debug.c | 58 +++++++++++++++++++++++- drivers/gpu/nvgpu/common/linux/driver_common.c | 13 ++++-- drivers/gpu/nvgpu/common/linux/ioctl_dbg.c | 26 +++++------ drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c | 3 +- 4 files changed, 78 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/nvgpu/common') diff --git a/drivers/gpu/nvgpu/common/linux/debug.c b/drivers/gpu/nvgpu/common/linux/debug.c index e8c0417a..87b35dc1 100644 --- a/drivers/gpu/nvgpu/common/linux/debug.c +++ b/drivers/gpu/nvgpu/common/linux/debug.c @@ -279,6 +279,59 @@ static int gk20a_railgating_debugfs_init(struct gk20a *g) return 0; } +static ssize_t timeouts_enabled_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + struct gk20a *g = file->private_data; + + if (nvgpu_is_timeouts_enabled(g)) + buf[0] = 'Y'; + else + buf[0] = 'N'; + buf[1] = '\n'; + buf[2] = 0x00; + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static ssize_t timeouts_enabled_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + int buf_size; + bool timeouts_enabled; + struct gk20a *g = file->private_data; + + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + if (strtobool(buf, &timeouts_enabled) == 0) { + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + if (timeouts_enabled == false) { + /* requesting to disable timeouts */ + if (g->timeouts_disabled_by_user == false) { + nvgpu_atomic_inc(&g->timeouts_disabled_refcount); + g->timeouts_disabled_by_user = true; + } + } else { + /* requesting to enable timeouts */ + if (g->timeouts_disabled_by_user == true) { + nvgpu_atomic_dec(&g->timeouts_disabled_refcount); + g->timeouts_disabled_by_user = false; + } + } + nvgpu_mutex_release(&g->dbg_sessions_lock); + } + + return count; +} + +static const struct file_operations timeouts_enabled_fops = { + .open = simple_open, + .read = timeouts_enabled_read, + .write = timeouts_enabled_write, +}; void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) { @@ -323,10 +376,11 @@ void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) S_IRUGO|S_IWUSR, l->debugfs, &g->gr_idle_timeout_default); l->debugfs_timeouts_enabled = - debugfs_create_bool("timeouts_enabled", + debugfs_create_file("timeouts_enabled", S_IRUGO|S_IWUSR, l->debugfs, - &g->timeouts_enabled); + g, + &timeouts_enabled_fops); l->debugfs_disable_bigpage = debugfs_create_file("disable_bigpage", diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c index 769f7e03..edc8aca8 100644 --- a/drivers/gpu/nvgpu/common/linux/driver_common.c +++ b/drivers/gpu/nvgpu/common/linux/driver_common.c @@ -96,12 +96,15 @@ static void nvgpu_init_timeout(struct gk20a *g) { struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); - g->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT; - if (nvgpu_platform_is_silicon(g)) - g->timeouts_enabled = true; - else if (nvgpu_platform_is_fpga(g)) { + g->timeouts_disabled_by_user = false; + nvgpu_atomic_set(&g->timeouts_disabled_refcount, 0); + + if (nvgpu_platform_is_silicon(g)) { + g->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT; + } else if (nvgpu_platform_is_fpga(g)) { g->gr_idle_timeout_default = GK20A_TIMEOUT_FPGA; - g->timeouts_enabled = true; + } else { + g->gr_idle_timeout_default = (u32)ULONG_MAX; } g->ch_wdt_timeout_ms = platform->ch_wdt_timeout_ms; } diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c index 2aba2664..31e7e2cb 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c @@ -228,7 +228,7 @@ static int nvgpu_dbg_gpu_ioctl_timeout(struct dbg_session_gk20a *dbg_s, int err; struct gk20a *g = dbg_s->g; - nvgpu_log_fn(g, "powergate mode = %d", args->enable); + nvgpu_log(g, gpu_dbg_fn, "timeout enable/disable = %d", args->enable); nvgpu_mutex_acquire(&g->dbg_sessions_lock); err = nvgpu_dbg_timeout_enable(dbg_s, args->enable); @@ -385,18 +385,14 @@ static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s, 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; - } + if (dbg_s->is_timeout_disabled == true) + nvgpu_atomic_dec(&g->timeouts_disabled_refcount); 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; - } + if (dbg_s->is_timeout_disabled == false) + nvgpu_atomic_inc(&g->timeouts_disabled_refcount); dbg_s->is_timeout_disabled = true; break; @@ -408,9 +404,11 @@ static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s, break; } - nvgpu_log(g, gpu_dbg_gpu_dbg, "Timeouts enabled : %s", - g->timeouts_enabled ? "Yes" : "No"); - + if (!err) + nvgpu_log(g, gpu_dbg_gpu_dbg, "dbg is timeout disabled %s, " + "timeouts disabled refcount %d", + dbg_s->is_timeout_disabled ? "true" : "false", + nvgpu_atomic_read(&g->timeouts_disabled_refcount)); return err; } @@ -1598,11 +1596,11 @@ static int nvgpu_ioctl_profiler_reserve(struct dbg_session_gk20a *dbg_s, static void nvgpu_dbg_gpu_ioctl_get_timeout(struct dbg_session_gk20a *dbg_s, struct nvgpu_dbg_gpu_timeout_args *args) { - int status; + bool status; struct gk20a *g = dbg_s->g; nvgpu_mutex_acquire(&g->dbg_sessions_lock); - status = g->timeouts_enabled; + status = nvgpu_is_timeouts_enabled(g); nvgpu_mutex_release(&g->dbg_sessions_lock); if (status) diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c index 5d3598b5..c5572603 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c @@ -424,7 +424,8 @@ int vgpu_probe(struct platform_device *pdev) dma_set_max_seg_size(dev, UINT_MAX); gk20a->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT; - gk20a->timeouts_enabled = true; + gk20a->timeouts_disabled_by_user = false; + nvgpu_atomic_set(&gk20a->timeouts_disabled_refcount, 0); vgpu_create_sysfs(dev); gk20a_init_gr(gk20a); -- cgit v1.2.2