diff --git a/drivers/gpu/nvgpu/common/linux/channel.c b/drivers/gpu/nvgpu/common/linux/channel.c index 1d4afcc8e..07bb393e2 100644 --- a/drivers/gpu/nvgpu/common/linux/channel.c +++ b/drivers/gpu/nvgpu/common/linux/channel.c @@ -469,6 +469,8 @@ static int gk20a_submit_prepare_syncs(struct channel_gk20a *c, * this condition. */ if (flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_WAIT) { + int max_wait_cmds = c->deterministic ? 1 : 0; + if (!pre_alloc_enabled) job->wait_cmd = nvgpu_kzalloc(g, sizeof(struct priv_cmd_entry)); @@ -481,7 +483,7 @@ static int gk20a_submit_prepare_syncs(struct channel_gk20a *c, if (flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE) { wait_fence_fd = fence->id; err = c->sync->wait_fd(c->sync, wait_fence_fd, - job->wait_cmd); + job->wait_cmd, max_wait_cmds); } else { err = c->sync->wait_syncpt(c->sync, fence->id, fence->value, @@ -758,8 +760,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c, need_sync_framework = force_need_sync_fence || gk20a_channel_sync_needs_sync_framework(g) || (flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE && - (flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_WAIT || - flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET)); + flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET); /* * Deferred clean-up is necessary for any of the following diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c index 236ddaaf4..25c576813 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c @@ -83,7 +83,7 @@ static int gk20a_channel_syncpt_wait_syncpt(struct gk20a_channel_sync *s, } static int gk20a_channel_syncpt_wait_fd(struct gk20a_channel_sync *s, int fd, - struct priv_cmd_entry *wait_cmd) + struct priv_cmd_entry *wait_cmd, int max_wait_cmds) { #ifdef CONFIG_SYNC int i; @@ -101,6 +101,11 @@ static int gk20a_channel_syncpt_wait_fd(struct gk20a_channel_sync *s, int fd, if (!sync_fence) return -EINVAL; + if (max_wait_cmds && sync_fence->num_fences > max_wait_cmds) { + sync_fence_put(sync_fence); + return -EINVAL; + } + /* validate syncpt ids */ for (i = 0; i < sync_fence->num_fences; i++) { pt = sync_pt_from_fence(sync_fence->cbs[i].sync_pt); @@ -473,7 +478,7 @@ static int gk20a_channel_semaphore_wait_syncpt( #ifdef CONFIG_SYNC static int semaphore_wait_fd_native(struct channel_gk20a *c, int fd, - struct priv_cmd_entry *wait_cmd) + struct priv_cmd_entry *wait_cmd, int max_wait_cmds) { struct sync_fence *sync_fence; int err; @@ -491,6 +496,11 @@ static int semaphore_wait_fd_native(struct channel_gk20a *c, int fd, goto put_fence; } + if (max_wait_cmds && sync_fence->num_fences > max_wait_cmds) { + err = -EINVAL; + goto put_fence; + } + err = gk20a_channel_alloc_priv_cmdbuf(c, wait_cmd_size * num_wait_cmds, wait_cmd); @@ -526,14 +536,13 @@ put_fence: static int gk20a_channel_semaphore_wait_fd( struct gk20a_channel_sync *s, int fd, - struct priv_cmd_entry *entry) + struct priv_cmd_entry *entry, int max_wait_cmds) { struct gk20a_channel_semaphore *sema = container_of(s, struct gk20a_channel_semaphore, ops); struct channel_gk20a *c = sema->c; #ifdef CONFIG_SYNC - - return semaphore_wait_fd_native(c, fd, entry); + return semaphore_wait_fd_native(c, fd, entry, max_wait_cmds); #else nvgpu_err(c->g, "trying to use sync fds with CONFIG_SYNC disabled"); diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h index da8cb2512..adbecbe1b 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h @@ -46,7 +46,7 @@ struct gk20a_channel_sync { * Returns a gpu cmdbuf that performs the wait when executed */ int (*wait_fd)(struct gk20a_channel_sync *s, int fd, - struct priv_cmd_entry *entry); + struct priv_cmd_entry *entry, int max_wait_cmds); /* Increment syncpoint/semaphore. * Returns