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 <ddutta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1829719
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
ddutta
2018-09-18 11:16:31 +05:30
committed by mobile promotions
parent 9f948ed07f
commit 80b5e2b8d6
6 changed files with 89 additions and 127 deletions

View File

@@ -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,

View File

@@ -31,6 +31,8 @@
#include <nvgpu/nvhost.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/os_fence.h>
#include <nvgpu/os_fence_syncpts.h>
#include <nvgpu/os_fence_semas.h>
#include <nvgpu/channel.h>
#include <nvgpu/channel_sync.h>
@@ -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;
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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,
};