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 <aparamakuru@nvidia.com>
Reviewed-on: http://git-master/r/1020917
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Aingara Paramakuru
2016-02-25 14:19:24 -05:00
committed by Terje Bergstrom
parent 032efd066e
commit 82da6ed595
5 changed files with 44 additions and 1 deletions

View File

@@ -44,6 +44,9 @@
#define NVGPU_BEGIN_AGGRESSIVE_SYNC_DESTROY_LIMIT 64 /* channels */ #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 struct channel_gk20a *allocate_channel(struct fifo_gk20a *f);
static void free_channel(struct fifo_gk20a *f, struct channel_gk20a *c); 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); 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, static int gk20a_channel_zcull_bind(struct channel_gk20a *ch,
struct nvgpu_zcull_bind_args *args) 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.free_inst = channel_gk20a_free_inst;
gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc; gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc;
gops->fifo.channel_set_priority = gk20a_channel_set_priority; 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, 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); ((struct nvgpu_runlist_interleave_args *)buf)->level);
gk20a_idle(dev); gk20a_idle(dev);
break; 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: default:
dev_dbg(&dev->dev, "unrecognized ioctl cmd: 0x%x", cmd); dev_dbg(&dev->dev, "unrecognized ioctl cmd: 0x%x", cmd);
err = -ENOTTY; err = -ENOTTY;

View File

@@ -275,5 +275,6 @@ int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g,
int timeslice_period, int timeslice_period,
int *__timeslice_timeout, int *__timeslice_scale); int *__timeslice_timeout, int *__timeslice_scale);
int gk20a_channel_set_priority(struct channel_gk20a *ch, u32 priority); 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 */ #endif /* CHANNEL_GK20A_H */

View File

@@ -269,6 +269,8 @@ struct gpu_ops {
int (*set_runlist_interleave)(struct gk20a *g, u32 id, int (*set_runlist_interleave)(struct gk20a *g, u32 id,
bool is_tsg, u32 runlist_id, bool is_tsg, u32 runlist_id,
u32 new_level); u32 new_level);
int (*channel_set_timeslice)(struct channel_gk20a *ch,
u32 timeslice);
} fifo; } fifo;
struct pmu_v { struct pmu_v {
/*used for change of enum zbc update cmd id from ver 0 to ver1*/ /*used for change of enum zbc update cmd id from ver 0 to ver1*/

View File

@@ -114,6 +114,7 @@ void gm20b_init_fifo(struct gpu_ops *gops)
gops->fifo.free_inst = channel_gk20a_free_inst; gops->fifo.free_inst = channel_gk20a_free_inst;
gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc; gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc;
gops->fifo.channel_set_priority = gk20a_channel_set_priority; 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.preempt_channel = gk20a_fifo_preempt_channel;
gops->fifo.update_runlist = gk20a_fifo_update_runlist; gops->fifo.update_runlist = gk20a_fifo_update_runlist;

View File

@@ -880,6 +880,12 @@ struct nvgpu_runlist_interleave_args {
#define NVGPU_RUNLIST_INTERLEAVE_LEVEL_HIGH 2 #define NVGPU_RUNLIST_INTERLEAVE_LEVEL_HIGH 2
#define NVGPU_RUNLIST_INTERLEAVE_NUM_LEVELS 3 #define NVGPU_RUNLIST_INTERLEAVE_NUM_LEVELS 3
/* controls how long a channel occupies an engine uninterrupted */
struct nvgpu_timeslice_args {
__u32 timeslice_us;
__u32 reserved;
};
#define NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD \ #define NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD \
_IOW(NVGPU_IOCTL_MAGIC, 5, struct nvgpu_set_nvmap_fd_args) _IOW(NVGPU_IOCTL_MAGIC, 5, struct nvgpu_set_nvmap_fd_args)
#define NVGPU_IOCTL_CHANNEL_SET_TIMEOUT \ #define NVGPU_IOCTL_CHANNEL_SET_TIMEOUT \
@@ -924,9 +930,11 @@ struct nvgpu_runlist_interleave_args {
_IOW(NVGPU_IOCTL_MAGIC, 119, struct nvgpu_channel_wdt_args) _IOW(NVGPU_IOCTL_MAGIC, 119, struct nvgpu_channel_wdt_args)
#define NVGPU_IOCTL_CHANNEL_SET_RUNLIST_INTERLEAVE \ #define NVGPU_IOCTL_CHANNEL_SET_RUNLIST_INTERLEAVE \
_IOW(NVGPU_IOCTL_MAGIC, 120, struct nvgpu_runlist_interleave_args) _IOW(NVGPU_IOCTL_MAGIC, 120, struct nvgpu_runlist_interleave_args)
#define NVGPU_IOCTL_CHANNEL_SET_TIMESLICE \
_IOW(NVGPU_IOCTL_MAGIC, 121, struct nvgpu_timeslice_args)
#define NVGPU_IOCTL_CHANNEL_LAST \ #define NVGPU_IOCTL_CHANNEL_LAST \
_IOC_NR(NVGPU_IOCTL_CHANNEL_SET_RUNLIST_INTERLEAVE) _IOC_NR(NVGPU_IOCTL_CHANNEL_SET_TIMESLICE)
#define NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvgpu_submit_gpfifo_args) #define NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvgpu_submit_gpfifo_args)
/* /*