mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
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:
committed by
mobile promotions
parent
9f948ed07f
commit
80b5e2b8d6
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user