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,
