From 82da6ed595a87c8a3038eecd75880ab21dd4c5de Mon Sep 17 00:00:00 2001 From: Aingara Paramakuru Date: Thu, 25 Feb 2016 14:19:24 -0500 Subject: gpu: nvgpu: add support to set channel timeslice As part of improving GPU scheduling, userspace can now set a channel's timeslice, within reasonable limits imposed by the kernel driver. JIRA VFND-1312 Bug 1729664 Change-Id: I4c3430c43437889b8685f12988d4b967bb7877bb Signed-off-by: Aingara Paramakuru Reviewed-on: http://git-master/r/1020917 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 1 + drivers/gpu/nvgpu/gk20a/gk20a.h | 2 ++ drivers/gpu/nvgpu/gm20b/fifo_gm20b.c | 1 + 4 files changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 654388cb..9b1f2987 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -44,6 +44,9 @@ #define NVGPU_BEGIN_AGGRESSIVE_SYNC_DESTROY_LIMIT 64 /* channels */ +#define NVGPU_CHANNEL_MIN_TIMESLICE_US 1000 +#define NVGPU_CHANNEL_MAX_TIMESLICE_US 50000 + static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f); static void free_channel(struct fifo_gk20a *f, struct channel_gk20a *c); @@ -2633,6 +2636,21 @@ int gk20a_channel_set_priority(struct channel_gk20a *ch, u32 priority) timeslice_timeout); } +int gk20a_channel_set_timeslice(struct channel_gk20a *ch, u32 timeslice) +{ + 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) + return -EINVAL; + + return channel_gk20a_set_schedule_params(ch, timeslice); +} + static int gk20a_channel_zcull_bind(struct channel_gk20a *ch, struct nvgpu_zcull_bind_args *args) { @@ -2785,6 +2803,7 @@ void gk20a_init_channel(struct gpu_ops *gops) gops->fifo.free_inst = channel_gk20a_free_inst; gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc; gops->fifo.channel_set_priority = gk20a_channel_set_priority; + gops->fifo.channel_set_timeslice = gk20a_channel_set_timeslice; } long gk20a_channel_ioctl(struct file *filp, @@ -3047,6 +3066,18 @@ long gk20a_channel_ioctl(struct file *filp, ((struct nvgpu_runlist_interleave_args *)buf)->level); gk20a_idle(dev); break; + case NVGPU_IOCTL_CHANNEL_SET_TIMESLICE: + err = gk20a_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = ch->g->ops.fifo.channel_set_timeslice(ch, + ((struct nvgpu_timeslice_args *)buf)->timeslice_us); + gk20a_idle(dev); + break; default: dev_dbg(&dev->dev, "unrecognized ioctl cmd: 0x%x", cmd); err = -ENOTTY; diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 3f5a657a..e3fbba3e 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h @@ -275,5 +275,6 @@ int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g, int timeslice_period, int *__timeslice_timeout, int *__timeslice_scale); int gk20a_channel_set_priority(struct channel_gk20a *ch, u32 priority); +int gk20a_channel_set_timeslice(struct channel_gk20a *ch, u32 timeslice); #endif /* CHANNEL_GK20A_H */ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index faccf04a..8b87c7aa 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -269,6 +269,8 @@ struct gpu_ops { int (*set_runlist_interleave)(struct gk20a *g, u32 id, bool is_tsg, u32 runlist_id, u32 new_level); + int (*channel_set_timeslice)(struct channel_gk20a *ch, + u32 timeslice); } fifo; struct pmu_v { /*used for change of enum zbc update cmd id from ver 0 to ver1*/ diff --git a/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c b/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c index 3fded03c..b9763224 100644 --- a/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c @@ -114,6 +114,7 @@ void gm20b_init_fifo(struct gpu_ops *gops) gops->fifo.free_inst = channel_gk20a_free_inst; gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc; gops->fifo.channel_set_priority = gk20a_channel_set_priority; + gops->fifo.channel_set_timeslice = gk20a_channel_set_timeslice; gops->fifo.preempt_channel = gk20a_fifo_preempt_channel; gops->fifo.update_runlist = gk20a_fifo_update_runlist; -- cgit v1.2.2