[PATCH 1/2] drm/syncobj: add an output syncobj parameter to find_fence
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Thu May 23 11:46:19 UTC 2019
We would like to get both the fence & the syncobj in i915 rather than
doing 2 calls to drm_syncobj_find() & drm_syncobj_find_fence().
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: Christian Koenig <Christian.Koenig at amd.com>
Cc: David(ChunMing) Zhou <David1.Zhou at amd.com>
Cc: Eric Anholt <eric at anholt.net>
CC: DRI-Devel <dri-devel at lists.freedesktop.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 ++-
drivers/gpu/drm/drm_syncobj.c | 45 +++++++++++++++++---------
drivers/gpu/drm/v3d/v3d_gem.c | 5 ++-
include/drm/drm_syncobj.h | 1 +
4 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 2f6239b6be6f..09fde3c73a2c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1124,10 +1124,11 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
uint32_t handle, u64 point,
u64 flags)
{
+ struct drm_syncobj *syncobj;
struct dma_fence *fence;
int r;
- r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence);
+ r = drm_syncobj_find_fence(p->filp, handle, point, flags, &syncobj, &fence);
if (r) {
DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n",
handle, point, r);
@@ -1136,6 +1137,7 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true);
dma_fence_put(fence);
+ drm_syncobj_put(syncobj);
return r;
}
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 3d400905100b..f2fd0c1fb1d3 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -222,29 +222,32 @@ static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
* @handle: sync object handle to lookup.
* @point: timeline point
* @flags: DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT or not
+ * @syncobj: out parameter for the syncobj
* @fence: out parameter for the fence
*
* This is just a convenience function that combines drm_syncobj_find() and
* drm_syncobj_fence_get().
*
- * Returns 0 on success or a negative error value on failure. On success @fence
- * contains a reference to the fence, which must be released by calling
- * dma_fence_put().
+ * Returns 0 on success or a negative error value on failure. On
+ * success @syncobj and @fence contains a reference respectively to
+ * the syncobj and to the fence, which must be released by calling
+ * respectively drm_syncobj_put() and dma_fence_put().
*/
int drm_syncobj_find_fence(struct drm_file *file_private,
u32 handle, u64 point, u64 flags,
+ struct drm_syncobj **syncobj,
struct dma_fence **fence)
{
- struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
struct syncobj_wait_entry wait;
u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT);
int ret;
- if (!syncobj)
+ *syncobj = drm_syncobj_find(file_private, handle);
+
+ if (!(*syncobj))
return -ENOENT;
- *fence = drm_syncobj_fence_get(syncobj);
- drm_syncobj_put(syncobj);
+ *fence = drm_syncobj_fence_get(*syncobj);
if (*fence) {
ret = dma_fence_chain_find_seqno(fence, point);
@@ -255,13 +258,15 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
ret = -EINVAL;
}
- if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
+ if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) {
+ drm_syncobj_put(*syncobj);
return ret;
+ }
memset(&wait, 0, sizeof(wait));
wait.task = current;
wait.point = point;
- drm_syncobj_fence_add_wait(syncobj, &wait);
+ drm_syncobj_fence_add_wait(*syncobj, &wait);
do {
set_current_state(TASK_INTERRUPTIBLE);
@@ -286,7 +291,10 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
*fence = wait.fence;
if (wait.node.next)
- drm_syncobj_remove_wait(syncobj, &wait);
+ drm_syncobj_remove_wait(*syncobj, &wait);
+
+ if (ret)
+ drm_syncobj_put(*syncobj);
return ret;
}
@@ -531,6 +539,7 @@ static int drm_syncobj_export_sync_file(struct drm_file *file_private,
int handle, int *p_fd)
{
int ret;
+ struct drm_syncobj *syncobj;
struct dma_fence *fence;
struct sync_file *sync_file;
int fd = get_unused_fd_flags(O_CLOEXEC);
@@ -538,13 +547,14 @@ static int drm_syncobj_export_sync_file(struct drm_file *file_private,
if (fd < 0)
return fd;
- ret = drm_syncobj_find_fence(file_private, handle, 0, 0, &fence);
+ ret = drm_syncobj_find_fence(file_private, handle, 0, 0, &syncobj, &fence);
if (ret)
goto err_put_fd;
sync_file = sync_file_create(fence);
dma_fence_put(fence);
+ drm_syncobj_put(syncobj);
if (!sync_file) {
ret = -EINVAL;
@@ -682,7 +692,8 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private,
struct drm_syncobj_transfer *args)
{
- struct drm_syncobj *timeline_syncobj = NULL;
+ struct drm_syncobj *timeline_syncobj;
+ struct drm_syncobj *src_syncobj;
struct dma_fence *fence;
struct dma_fence_chain *chain;
int ret;
@@ -693,7 +704,7 @@ static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private,
}
ret = drm_syncobj_find_fence(file_private, args->src_handle,
args->src_point, args->flags,
- &fence);
+ &src_syncobj, &fence);
if (ret)
goto err;
chain = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
@@ -704,6 +715,7 @@ static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private,
drm_syncobj_add_point(timeline_syncobj, chain, fence, args->dst_point);
err1:
dma_fence_put(fence);
+ drm_syncobj_put(src_syncobj);
err:
drm_syncobj_put(timeline_syncobj);
@@ -714,7 +726,8 @@ static int
drm_syncobj_transfer_to_binary(struct drm_file *file_private,
struct drm_syncobj_transfer *args)
{
- struct drm_syncobj *binary_syncobj = NULL;
+ struct drm_syncobj *binary_syncobj;
+ struct drm_syncobj *src_syncobj;
struct dma_fence *fence;
int ret;
@@ -722,11 +735,13 @@ drm_syncobj_transfer_to_binary(struct drm_file *file_private,
if (!binary_syncobj)
return -ENOENT;
ret = drm_syncobj_find_fence(file_private, args->src_handle,
- args->src_point, args->flags, &fence);
+ args->src_point, args->flags,
+ &src_syncobj, &fence);
if (ret)
goto err;
drm_syncobj_replace_fence(binary_syncobj, fence);
dma_fence_put(fence);
+ drm_syncobj_put(src_syncobj);
err:
drm_syncobj_put(binary_syncobj);
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
index 27e0f87075d9..26bd3a2e39ca 100644
--- a/drivers/gpu/drm/v3d/v3d_gem.c
+++ b/drivers/gpu/drm/v3d/v3d_gem.c
@@ -431,6 +431,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
struct v3d_job *job, void (*free)(struct kref *ref),
u32 in_sync)
{
+ struct drm_syncobj *in_syncobj = NULL;
struct dma_fence *in_fence = NULL;
int ret;
@@ -443,10 +444,12 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
xa_init_flags(&job->deps, XA_FLAGS_ALLOC);
- ret = drm_syncobj_find_fence(file_priv, in_sync, 0, 0, &in_fence);
+ ret = drm_syncobj_find_fence(file_priv, in_sync, 0, 0, &syncobj, &in_fence);
if (ret == -EINVAL)
goto fail;
+ drm_syncobj_put(in_sync);
+
ret = drm_gem_fence_array_add(&job->deps, in_fence);
if (ret)
goto fail;
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index 6cf7243a1dc5..08eca690f783 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -121,6 +121,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
struct dma_fence *fence);
int drm_syncobj_find_fence(struct drm_file *file_private,
u32 handle, u64 point, u64 flags,
+ struct drm_syncobj **syncobj,
struct dma_fence **fence);
void drm_syncobj_free(struct kref *kref);
int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
--
2.21.0.392.gf8f6787159e
More information about the dri-devel
mailing list