From 80b5e2b8d63d2fd53d4eccdf080303255042aeb4 Mon Sep 17 00:00:00 2001 From: ddutta Date: Tue, 18 Sep 2018 11:16:31 +0530 Subject: [PATCH] gpu: nvgpu: remove os_fence dependency from channel_sync Move the wait_cmd_buffer programming for channel_sync->wait_fd to channel_sync.c. nvgpu_os_fence->program_waits interface is now removed. channel_sync can directly retrieve syncpt/semaphore from the interfaces of struct nvgpu_os_fence_syncpt and struct nvgpu_os_fence_sema and use it for the wait programming. Also, change int to u32 for some variables such as num_fences, max_wait_size and wait_cmd_size. Jira NVGPU-1093 Change-Id: I19c1b10d676caff49ce57861091f7f0ea65e7676 Signed-off-by: Debarshi Dutta Reviewed-on: https://git-master.nvidia.com/r/1829719 Reviewed-by: svc-mobile-coverity Reviewed-by: Konsta Holtta GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/submit.c | 2 +- drivers/gpu/nvgpu/common/sync/channel_sync.c | 96 +++++++++++++++++-- .../gpu/nvgpu/include/nvgpu/channel_sync.h | 10 +- drivers/gpu/nvgpu/include/nvgpu/os_fence.h | 9 -- .../nvgpu/os/linux/os_fence_android_sema.c | 43 +-------- .../nvgpu/os/linux/os_fence_android_syncpt.c | 56 ----------- 6 files changed, 89 insertions(+), 127 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/submit.c b/drivers/gpu/nvgpu/common/fifo/submit.c index 5e218fbc0..b6bf840ad 100644 --- a/drivers/gpu/nvgpu/common/fifo/submit.c +++ b/drivers/gpu/nvgpu/common/fifo/submit.c @@ -80,7 +80,7 @@ static int nvgpu_submit_prepare_syncs(struct channel_gk20a *c, * submission when user requested and the wait hasn't expired. */ if (flags & NVGPU_SUBMIT_FLAGS_FENCE_WAIT) { - int max_wait_cmds = c->deterministic ? 1 : 0; + u32 max_wait_cmds = c->deterministic ? 1U : 0U; if (!pre_alloc_enabled) { job->wait_cmd = nvgpu_kzalloc(g, diff --git a/drivers/gpu/nvgpu/common/sync/channel_sync.c b/drivers/gpu/nvgpu/common/sync/channel_sync.c index b40de834a..4d629ece7 100644 --- a/drivers/gpu/nvgpu/common/sync/channel_sync.c +++ b/drivers/gpu/nvgpu/common/sync/channel_sync.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include @@ -47,7 +49,7 @@ struct nvgpu_channel_sync_syncpt { struct nvgpu_mem syncpt_buf; }; -int channel_sync_syncpt_gen_wait_cmd(struct channel_gk20a *c, +static int channel_sync_syncpt_gen_wait_cmd(struct channel_gk20a *c, u32 id, u32 thresh, struct priv_cmd_entry *wait_cmd, u32 wait_cmd_size, u32 pos, bool preallocated) { @@ -100,24 +102,67 @@ static int channel_sync_syncpt_wait_raw(struct nvgpu_channel_sync *s, } static int channel_sync_syncpt_wait_fd(struct nvgpu_channel_sync *s, int fd, - struct priv_cmd_entry *wait_cmd, int max_wait_cmds) + struct priv_cmd_entry *wait_cmd, u32 max_wait_cmds) { struct nvgpu_os_fence os_fence = {0}; + struct nvgpu_os_fence_syncpt os_fence_syncpt = {0}; struct nvgpu_channel_sync_syncpt *sp = container_of(s, struct nvgpu_channel_sync_syncpt, ops); struct channel_gk20a *c = sp->c; int err = 0; + u32 i, num_fences, wait_cmd_size; + u32 syncpt_id = 0U; + u32 syncpt_thresh = 0U; err = nvgpu_os_fence_fdget(&os_fence, c, fd); if (err != 0) { return -EINVAL; } - err = os_fence.ops->program_waits(&os_fence, - wait_cmd, c, max_wait_cmds); + err = nvgpu_os_fence_get_syncpts(&os_fence_syncpt, &os_fence); + if (err != 0) { + goto cleanup; + } + num_fences = nvgpu_os_fence_syncpt_get_num_syncpoints(&os_fence_syncpt); + + if (num_fences == 0U) { + goto cleanup; + } + + if ((max_wait_cmds != 0U) && (num_fences > max_wait_cmds)) { + err = -EINVAL; + goto cleanup; + } + + for (i = 0; i < num_fences; i++) { + nvgpu_os_fence_syncpt_extract_nth_syncpt( + &os_fence_syncpt, i, &syncpt_id, &syncpt_thresh); + if ((syncpt_id == 0U) || !nvgpu_nvhost_syncpt_is_valid_pt_ext( + c->g->nvhost_dev, syncpt_id)) { + err = -EINVAL; + goto cleanup; + } + } + + wait_cmd_size = c->g->ops.fifo.get_syncpt_wait_cmd_size(); + err = gk20a_channel_alloc_priv_cmdbuf(c, + wait_cmd_size * num_fences, wait_cmd); + if (err != 0) { + nvgpu_err(c->g, "not enough priv cmd buffer space"); + err = -EINVAL; + goto cleanup; + } + + for (i = 0; i < num_fences; i++) { + nvgpu_os_fence_syncpt_extract_nth_syncpt( + &os_fence_syncpt, i, &syncpt_id, &syncpt_thresh); + err = channel_sync_syncpt_gen_wait_cmd(c, syncpt_id, + syncpt_thresh, wait_cmd, wait_cmd_size, i, true); + } + +cleanup: os_fence.ops->drop_ref(&os_fence); - return err; } @@ -388,7 +433,7 @@ static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c, } } -void channel_sync_semaphore_gen_wait_cmd(struct channel_gk20a *c, +static void channel_sync_semaphore_gen_wait_cmd(struct channel_gk20a *c, struct nvgpu_semaphore *sema, struct priv_cmd_entry *wait_cmd, u32 wait_cmd_size, u32 pos) { @@ -418,25 +463,56 @@ static int channel_sync_semaphore_wait_raw_syncpt( static int channel_sync_semaphore_wait_fd( struct nvgpu_channel_sync *s, int fd, - struct priv_cmd_entry *entry, int max_wait_cmds) + struct priv_cmd_entry *entry, u32 max_wait_cmds) { struct nvgpu_channel_sync_semaphore *sema = container_of(s, struct nvgpu_channel_sync_semaphore, ops); struct channel_gk20a *c = sema->c; struct nvgpu_os_fence os_fence = {0}; + struct nvgpu_os_fence_sema os_fence_sema = {0}; int err; + u32 wait_cmd_size, i, num_fences; + struct nvgpu_semaphore *semaphore = NULL; err = nvgpu_os_fence_fdget(&os_fence, c, fd); if (err != 0) { return err; } - err = os_fence.ops->program_waits(&os_fence, - entry, c, max_wait_cmds); + err = nvgpu_os_fence_get_semas(&os_fence_sema, &os_fence); + if (err != 0) { + goto cleanup; + } + num_fences = nvgpu_os_fence_sema_get_num_semaphores(&os_fence_sema); + + if (num_fences == 0U) { + goto cleanup; + } + + if ((max_wait_cmds != 0U) && (num_fences > max_wait_cmds)) { + err = -EINVAL; + goto cleanup; + } + + wait_cmd_size = c->g->ops.fifo.get_sema_wait_cmd_size(); + err = gk20a_channel_alloc_priv_cmdbuf(c, + wait_cmd_size * num_fences, entry); + if (err != 0) { + nvgpu_err(c->g, "not enough priv cmd buffer space"); + goto cleanup; + } + + for (i = 0; i < num_fences; i++) { + nvgpu_os_fence_sema_extract_nth_semaphore( + &os_fence_sema, i, &semaphore); + channel_sync_semaphore_gen_wait_cmd(c, semaphore, entry, + wait_cmd_size, i); + } + +cleanup: os_fence.ops->drop_ref(&os_fence); - return err; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/channel_sync.h b/drivers/gpu/nvgpu/include/nvgpu/channel_sync.h index f0b2b8605..8382d51e5 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/channel_sync.h +++ b/drivers/gpu/nvgpu/include/nvgpu/channel_sync.h @@ -48,7 +48,7 @@ struct nvgpu_channel_sync { * Returns a gpu cmdbuf that performs the wait when executed */ int (*wait_fd)(struct nvgpu_channel_sync *s, int fd, - struct priv_cmd_entry *entry, int max_wait_cmds); + struct priv_cmd_entry *entry, u32 max_wait_cmds); /* Increment syncpoint/semaphore. * Returns @@ -96,14 +96,6 @@ struct nvgpu_channel_sync { void (*destroy)(struct nvgpu_channel_sync *s); }; -void channel_sync_semaphore_gen_wait_cmd(struct channel_gk20a *c, - struct nvgpu_semaphore *sema, struct priv_cmd_entry *wait_cmd, - u32 wait_cmd_size, u32 pos); - -int channel_sync_syncpt_gen_wait_cmd(struct channel_gk20a *c, - u32 id, u32 thresh, struct priv_cmd_entry *wait_cmd, - u32 wait_cmd_size, u32 pos, bool preallocated); - void nvgpu_channel_sync_destroy(struct nvgpu_channel_sync *sync, bool set_safe_state); struct nvgpu_channel_sync *nvgpu_channel_sync_create(struct channel_gk20a *c, diff --git a/drivers/gpu/nvgpu/include/nvgpu/os_fence.h b/drivers/gpu/nvgpu/include/nvgpu/os_fence.h index 272b07614..b779a64fc 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/os_fence.h +++ b/drivers/gpu/nvgpu/include/nvgpu/os_fence.h @@ -45,15 +45,6 @@ struct nvgpu_os_fence; * struct nvgpu_os_fence depends on the following ops structure */ struct nvgpu_os_fence_ops { - /* - * This API is used to iterate through multiple fence points within the - * fence and program the pushbuffer method for wait command. - */ - int (*program_waits)(struct nvgpu_os_fence *s, - struct priv_cmd_entry *wait_cmd, - struct channel_gk20a *c, - int max_wait_cmds); - /* * This should be the last operation on the OS fence. The * OS fence acts as a place-holder for the underlying fence diff --git a/drivers/gpu/nvgpu/os/linux/os_fence_android_sema.c b/drivers/gpu/nvgpu/os/linux/os_fence_android_sema.c index 096b8cf98..8ffaf4720 100644 --- a/drivers/gpu/nvgpu/os/linux/os_fence_android_sema.c +++ b/drivers/gpu/nvgpu/os/linux/os_fence_android_sema.c @@ -31,49 +31,7 @@ #include "../drivers/staging/android/sync.h" -int nvgpu_os_fence_sema_wait_gen_cmd(struct nvgpu_os_fence *s, - struct priv_cmd_entry *wait_cmd, - struct channel_gk20a *c, - int max_wait_cmds) -{ - int err; - int wait_cmd_size; - int num_wait_cmds; - int i; - struct nvgpu_semaphore *sema; - struct sync_fence *sync_fence = nvgpu_get_sync_fence(s); - - wait_cmd_size = c->g->ops.fifo.get_sema_wait_cmd_size(); - - num_wait_cmds = sync_fence->num_fences; - if (num_wait_cmds == 0) - return 0; - - if (max_wait_cmds && num_wait_cmds > max_wait_cmds) - return -EINVAL; - - err = gk20a_channel_alloc_priv_cmdbuf(c, - wait_cmd_size * num_wait_cmds, - wait_cmd); - if (err) { - nvgpu_err(c->g, "not enough priv cmd buffer space"); - return err; - } - - for (i = 0; i < num_wait_cmds; i++) { - struct sync_pt *pt = sync_pt_from_fence( - sync_fence->cbs[i].sync_pt); - - sema = gk20a_sync_pt_sema(pt); - channel_sync_semaphore_gen_wait_cmd(c, sema, wait_cmd, - wait_cmd_size, i); - } - - return 0; -} - static const struct nvgpu_os_fence_ops sema_ops = { - .program_waits = nvgpu_os_fence_sema_wait_gen_cmd, .drop_ref = nvgpu_os_fence_android_drop_ref, .install_fence = nvgpu_os_fence_android_install_fd, }; @@ -143,3 +101,4 @@ int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out, return 0; } + diff --git a/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c b/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c index f20761db2..f9f274d17 100644 --- a/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c +++ b/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c @@ -31,63 +31,7 @@ #include "../drivers/staging/android/sync.h" -int nvgpu_os_fence_syncpt_wait_gen_cmd(struct nvgpu_os_fence *s, - struct priv_cmd_entry *wait_cmd, - struct channel_gk20a *c, - int max_wait_cmds) -{ - int err; - int wait_cmd_size; - int num_wait_cmds; - int i; - u32 wait_id; - struct sync_pt *pt; - - struct sync_fence *sync_fence = (struct sync_fence *)s->priv; - - if (max_wait_cmds && sync_fence->num_fences > max_wait_cmds) - 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); - wait_id = nvgpu_nvhost_sync_pt_id(pt); - if (!wait_id || !nvgpu_nvhost_syncpt_is_valid_pt_ext( - c->g->nvhost_dev, wait_id)) { - return -EINVAL; - } - } - - num_wait_cmds = nvgpu_nvhost_sync_num_pts(sync_fence); - if (num_wait_cmds == 0) - return 0; - - wait_cmd_size = c->g->ops.fifo.get_syncpt_wait_cmd_size(); - err = gk20a_channel_alloc_priv_cmdbuf(c, - wait_cmd_size * num_wait_cmds, wait_cmd); - if (err) { - nvgpu_err(c->g, - "not enough priv cmd buffer space"); - return err; - } - - for (i = 0; i < sync_fence->num_fences; i++) { - struct sync_pt *pt = sync_pt_from_fence( - sync_fence->cbs[i].sync_pt); - u32 wait_id = nvgpu_nvhost_sync_pt_id(pt); - u32 wait_value = nvgpu_nvhost_sync_pt_thresh(pt); - - err = channel_sync_syncpt_gen_wait_cmd(c, wait_id, wait_value, - wait_cmd, wait_cmd_size, i, true); - } - - WARN_ON(i != num_wait_cmds); - - return 0; -} - static const struct nvgpu_os_fence_ops syncpt_ops = { - .program_waits = nvgpu_os_fence_syncpt_wait_gen_cmd, .drop_ref = nvgpu_os_fence_android_drop_ref, .install_fence = nvgpu_os_fence_android_install_fd, };