diff options
author | David Li <davli@nvidia.com> | 2018-04-26 05:00:01 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-05-18 02:34:20 -0400 |
commit | a807cf20419af737a79a3d0c7fcc1068ac6b724a (patch) | |
tree | 4efc94d09217bd5e7fdad973b8dacfdee9bab8dd /drivers/gpu/nvgpu/common | |
parent | 8ac538e1b16c68ef4a5b9d85a82bbfc2b3fabd72 (diff) |
gpu: nvgpu: add NVGPU_IOCTL_CHANNEL_RESCHEDULE_RUNLIST
Add NVGPU_IOCTL_CHANNEL_RESCHEDULE_RUNLIST ioctl to reschedule runlist,
and optionally check host and FECS status to preempt pending load of
context not belonging to the calling channel on GR engine during context
switch.
This should be called immediately after a submit to decrease worst case
submit to start latency for high interleave channel.
There is less than 0.002% chance that the ioctl blocks up to couple
miliseconds due to race condition of FECS status changing while being read.
For GV11B it will always preempt pending load of unwanted context since
there is no chance that ioctl blocks due to race condition.
Also fix bug with host reschedule for multiple runlists which needs to
write both runlist registers.
Bug 1987640
Bug 1924808
Change-Id: I0b7e2f91bd18b0b20928e5a3311b9426b1bf1848
Signed-off-by: David Li <davli@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1549050
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/channel.c | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_channel.c | 25 |
2 files changed, 21 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/channel.c b/drivers/gpu/nvgpu/common/linux/channel.c index 1e170b30..f189d3ed 100644 --- a/drivers/gpu/nvgpu/common/linux/channel.c +++ b/drivers/gpu/nvgpu/common/linux/channel.c | |||
@@ -64,9 +64,6 @@ u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) | |||
64 | if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SKIP_BUFFER_REFCOUNTING) | 64 | if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SKIP_BUFFER_REFCOUNTING) |
65 | flags |= NVGPU_SUBMIT_FLAGS_SKIP_BUFFER_REFCOUNTING; | 65 | flags |= NVGPU_SUBMIT_FLAGS_SKIP_BUFFER_REFCOUNTING; |
66 | 66 | ||
67 | if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_RESCHEDULE_RUNLIST) | ||
68 | flags |= NVGPU_SUBMIT_FLAGS_RESCHEDULE_RUNLIST; | ||
69 | |||
70 | return flags; | 67 | return flags; |
71 | } | 68 | } |
72 | 69 | ||
@@ -1008,10 +1005,6 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c, | |||
1008 | 1005 | ||
1009 | g->ops.fifo.userd_gp_put(g, c); | 1006 | g->ops.fifo.userd_gp_put(g, c); |
1010 | 1007 | ||
1011 | if ((NVGPU_SUBMIT_FLAGS_RESCHEDULE_RUNLIST & flags) && | ||
1012 | g->ops.fifo.reschedule_runlist) | ||
1013 | g->ops.fifo.reschedule_runlist(g, c->runlist_id); | ||
1014 | |||
1015 | /* No hw access beyond this point */ | 1008 | /* No hw access beyond this point */ |
1016 | if (c->deterministic) | 1009 | if (c->deterministic) |
1017 | nvgpu_rwsem_up_read(&g->deterministic_busy); | 1010 | nvgpu_rwsem_up_read(&g->deterministic_busy); |
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c index 606c5251..c1492cad 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c | |||
@@ -789,10 +789,6 @@ static int gk20a_ioctl_channel_submit_gpfifo( | |||
789 | if (ch->has_timedout) | 789 | if (ch->has_timedout) |
790 | return -ETIMEDOUT; | 790 | return -ETIMEDOUT; |
791 | 791 | ||
792 | if ((NVGPU_SUBMIT_GPFIFO_FLAGS_RESCHEDULE_RUNLIST & args->flags) && | ||
793 | !capable(CAP_SYS_NICE)) | ||
794 | return -EPERM; | ||
795 | |||
796 | nvgpu_get_fence_args(&args->fence, &fence); | 792 | nvgpu_get_fence_args(&args->fence, &fence); |
797 | submit_flags = | 793 | submit_flags = |
798 | nvgpu_submit_gpfifo_user_flags_to_common_flags(args->flags); | 794 | nvgpu_submit_gpfifo_user_flags_to_common_flags(args->flags); |
@@ -1291,6 +1287,27 @@ long gk20a_channel_ioctl(struct file *filp, | |||
1291 | err = gk20a_fifo_preempt(ch->g, ch); | 1287 | err = gk20a_fifo_preempt(ch->g, ch); |
1292 | gk20a_idle(ch->g); | 1288 | gk20a_idle(ch->g); |
1293 | break; | 1289 | break; |
1290 | case NVGPU_IOCTL_CHANNEL_RESCHEDULE_RUNLIST: | ||
1291 | if (!capable(CAP_SYS_NICE)) { | ||
1292 | err = -EPERM; | ||
1293 | break; | ||
1294 | } | ||
1295 | if (!ch->g->ops.fifo.reschedule_runlist) { | ||
1296 | err = -ENOSYS; | ||
1297 | break; | ||
1298 | } | ||
1299 | err = gk20a_busy(ch->g); | ||
1300 | if (err) { | ||
1301 | dev_err(dev, | ||
1302 | "%s: failed to host gk20a for ioctl cmd: 0x%x", | ||
1303 | __func__, cmd); | ||
1304 | break; | ||
1305 | } | ||
1306 | err = ch->g->ops.fifo.reschedule_runlist(ch, | ||
1307 | NVGPU_RESCHEDULE_RUNLIST_PREEMPT_NEXT & | ||
1308 | ((struct nvgpu_reschedule_runlist_args *)buf)->flags); | ||
1309 | gk20a_idle(ch->g); | ||
1310 | break; | ||
1294 | case NVGPU_IOCTL_CHANNEL_FORCE_RESET: | 1311 | case NVGPU_IOCTL_CHANNEL_FORCE_RESET: |
1295 | err = gk20a_busy(ch->g); | 1312 | err = gk20a_busy(ch->g); |
1296 | if (err) { | 1313 | if (err) { |