Skip to content

Commit

Permalink
drm/msm: Fix wait_fence submitqueue leak
Browse files Browse the repository at this point in the history
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: a61acbb ("drm/msm: Track "seqno" fences by idr")
Signed-off-by: Rob Clark <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Rob Clark <[email protected]>
  • Loading branch information
robclark committed Nov 21, 2021
1 parent 3466d9e commit ea0006d
Showing 1 changed file with 29 additions and 20 deletions.
49 changes: 29 additions & 20 deletions drivers/gpu/drm/msm/msm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -967,29 +967,12 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
return ret;
}

static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
struct drm_file *file)
static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,
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;
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)
* back to underlying dma-fence
Expand All @@ -1001,7 +984,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
ret = mutex_lock_interruptible(&queue->lock);
if (ret)
return ret;
fence = idr_find(&queue->fence_idr, args->fence);
fence = idr_find(&queue->fence_idr, fence_id);
if (fence)
fence = dma_fence_get_rcu(fence);
mutex_unlock(&queue->lock);
Expand All @@ -1017,6 +1000,32 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
}

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);

return ret;
Expand Down

0 comments on commit ea0006d

Please sign in to comment.