From f15a86f26527505cbe0de96ecb56736eb1686b87 Mon Sep 17 00:00:00 2001 From: Peter Boonstoppel Date: Mon, 28 Nov 2016 17:33:30 -0800 Subject: gpu: nvgpu: Add sysfs nodes for timeslice min/max The timeslice values that can be selected for a particular channel/tsg are bounded by a static min/max. This change introduces two sysfs nodes that allow these bounds to be configured from userspace. min_timeslice_us max_timeslice_us Bug 200251974 Bug 1854791 Change-Id: I5d5a14225eee4090e418c7e43629324114f60768 Signed-off-by: Peter Boonstoppel Reviewed-on: http://git-master/r/1280372 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 9 +++-- drivers/gpu/nvgpu/gk20a/gk20a.h | 2 ++ drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 63 ++++++++++++++++++++++++++++++++- drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 9 ++--- drivers/gpu/nvgpu/nvgpu_common.c | 5 ++- 5 files changed, 75 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 40d6d91c..6cbbdeb0 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -44,9 +44,6 @@ #define NVMAP_HANDLE_PARAM_SIZE 1 -#define NVGPU_CHANNEL_MIN_TIMESLICE_US 1000 -#define NVGPU_CHANNEL_MAX_TIMESLICE_US 50000 - /* * Although channels do have pointers back to the gk20a struct that they were * created under in cases where the driver is killed that pointer can be bad. @@ -3345,14 +3342,16 @@ int gk20a_channel_set_priority(struct channel_gk20a *ch, u32 priority) int gk20a_channel_set_timeslice(struct channel_gk20a *ch, u32 timeslice) { + struct gk20a *g = ch->g; + if (gk20a_is_channel_marked_as_tsg(ch)) { gk20a_err(dev_from_gk20a(ch->g), "invalid operation for TSG!\n"); return -EINVAL; } - if (timeslice < NVGPU_CHANNEL_MIN_TIMESLICE_US || - timeslice > NVGPU_CHANNEL_MAX_TIMESLICE_US) + if (timeslice < g->min_timeslice_us || + timeslice > g->max_timeslice_us) return -EINVAL; ch->timeslice_us = timeslice; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index cf147ae8..ff8ffc4f 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -840,6 +840,8 @@ struct gk20a { u32 timeslice_low_priority_us; u32 timeslice_medium_priority_us; u32 timeslice_high_priority_us; + u32 min_timeslice_us; + u32 max_timeslice_us; #if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0) u32 runlist_interleave; #else diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index a2980354..307fb681 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c @@ -3,7 +3,7 @@ * * GK20A Graphics * - * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2017, 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, @@ -756,6 +756,63 @@ static ssize_t tpc_fs_mask_read(struct device *dev, static DEVICE_ATTR(tpc_fs_mask, ROOTRW, tpc_fs_mask_read, tpc_fs_mask_store); +static ssize_t min_timeslice_us_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", g->min_timeslice_us); +} + +static ssize_t min_timeslice_us_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val > g->max_timeslice_us) + return -EINVAL; + + g->min_timeslice_us = val; + + return count; +} + +static DEVICE_ATTR(min_timeslice_us, ROOTRW, min_timeslice_us_read, + min_timeslice_us_store); + +static ssize_t max_timeslice_us_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", g->max_timeslice_us); +} + +static ssize_t max_timeslice_us_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val < g->min_timeslice_us) + return -EINVAL; + + g->max_timeslice_us = val; + + return count; +} + +static DEVICE_ATTR(max_timeslice_us, ROOTRW, max_timeslice_us_read, + max_timeslice_us_store); + + void gk20a_remove_sysfs(struct device *dev) { struct gk20a *g = get_gk20a(dev); @@ -782,6 +839,8 @@ void gk20a_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_aelpg_enable); device_remove_file(dev, &dev_attr_allow_all); device_remove_file(dev, &dev_attr_tpc_fs_mask); + device_remove_file(dev, &dev_attr_min_timeslice_us); + device_remove_file(dev, &dev_attr_max_timeslice_us); if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev)) { sysfs_remove_link(&g->host1x_dev->dev.kobj, dev_name(dev)); @@ -822,6 +881,8 @@ void gk20a_create_sysfs(struct device *dev) error |= device_create_file(dev, &dev_attr_aelpg_enable); error |= device_create_file(dev, &dev_attr_allow_all); error |= device_create_file(dev, &dev_attr_tpc_fs_mask); + error |= device_create_file(dev, &dev_attr_min_timeslice_us); + error |= device_create_file(dev, &dev_attr_max_timeslice_us); if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev)) { error |= sysfs_create_link(&g->host1x_dev->dev.kobj, diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index 3b2cca0d..81a4b78e 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2017, 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, @@ -26,9 +26,6 @@ #include -#define NVGPU_TSG_MIN_TIMESLICE_US 1000 -#define NVGPU_TSG_MAX_TIMESLICE_US 50000 - struct tsg_private { struct gk20a *g; struct tsg_gk20a *tsg; @@ -367,8 +364,8 @@ int gk20a_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice) { struct gk20a *g = tsg->g; - if (timeslice < NVGPU_TSG_MIN_TIMESLICE_US || - timeslice > NVGPU_TSG_MAX_TIMESLICE_US) + if (timeslice < g->min_timeslice_us || + timeslice > g->max_timeslice_us) return -EINVAL; gk20a_channel_get_timescale_from_timeslice(g, timeslice, diff --git a/drivers/gpu/nvgpu/nvgpu_common.c b/drivers/gpu/nvgpu/nvgpu_common.c index a2673b26..7c12616f 100644 --- a/drivers/gpu/nvgpu/nvgpu_common.c +++ b/drivers/gpu/nvgpu/nvgpu_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2017, 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, @@ -69,6 +69,9 @@ static void nvgpu_init_timeslice(struct gk20a *g) g->timeslice_low_priority_us = 1300; g->timeslice_medium_priority_us = 2600; g->timeslice_high_priority_us = 5200; + + g->min_timeslice_us = 1000; + g->max_timeslice_us = 50000; } static void nvgpu_init_pm_vars(struct gk20a *g) -- cgit v1.2.2