Commit ea0006d3 authored by Rob Clark's avatar Rob Clark

drm/msm: Fix wait_fence submitqueue leak

We weren't dropping the submitqueue reference in all paths.  In
particular, when the fence has already been signalled. Split out
a helper to simplify handling this in the various different return
paths.

Fixes: a61acbbe ("drm/msm: Track "seqno" fences by idr")
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Link: https://lore.kernel.org/r/20211111192457.747899-2-robdclark@gmail.comSigned-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 3466d9e2
...@@ -967,29 +967,12 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, ...@@ -967,29 +967,12 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
return ret; return ret;
} }
static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,
struct drm_file *file) ktime_t timeout)
{ {
struct msm_drm_private *priv = dev->dev_private;
struct drm_msm_wait_fence *args = data;
ktime_t timeout = to_ktime(args->timeout);
struct msm_gpu_submitqueue *queue;
struct msm_gpu *gpu = priv->gpu;
struct dma_fence *fence; struct dma_fence *fence;
int ret; int ret;
if (args->pad) {
DRM_ERROR("invalid pad: %08x\n", args->pad);
return -EINVAL;
}
if (!gpu)
return 0;
queue = msm_submitqueue_get(file->driver_priv, args->queueid);
if (!queue)
return -ENOENT;
/* /*
* Map submitqueue scoped "seqno" (which is actually an idr key) * Map submitqueue scoped "seqno" (which is actually an idr key)
* back to underlying dma-fence * back to underlying dma-fence
...@@ -1001,7 +984,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, ...@@ -1001,7 +984,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
ret = mutex_lock_interruptible(&queue->lock); ret = mutex_lock_interruptible(&queue->lock);
if (ret) if (ret)
return ret; return ret;
fence = idr_find(&queue->fence_idr, args->fence); fence = idr_find(&queue->fence_idr, fence_id);
if (fence) if (fence)
fence = dma_fence_get_rcu(fence); fence = dma_fence_get_rcu(fence);
mutex_unlock(&queue->lock); mutex_unlock(&queue->lock);
...@@ -1017,6 +1000,32 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, ...@@ -1017,6 +1000,32 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
} }
dma_fence_put(fence); dma_fence_put(fence);
return ret;
}
static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
struct drm_file *file)
{
struct msm_drm_private *priv = dev->dev_private;
struct drm_msm_wait_fence *args = data;
struct msm_gpu_submitqueue *queue;
int ret;
if (args->pad) {
DRM_ERROR("invalid pad: %08x\n", args->pad);
return -EINVAL;
}
if (!priv->gpu)
return 0;
queue = msm_submitqueue_get(file->driver_priv, args->queueid);
if (!queue)
return -ENOENT;
ret = wait_fence(queue, args->fence, to_ktime(args->timeout));
msm_submitqueue_put(queue); msm_submitqueue_put(queue);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment