[CAUTION: External Email]
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@xxxxxxxxx>
Cc: Christian Koenig
<Christian.Koenig@xxxxxxx>
Cc: David(ChunMing) Zhou
<David1.Zhou@xxxxxxx>
Cc: Eric Anholt
<eric@xxxxxxxxxx>
CC: DRI-Devel
<dri-devel@xxxxxxxxxxxxxxxxxxxxx>
---
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