Commit 44c20087 authored by Rob Clark's avatar Rob Clark

drm/msm: Use idr_preload()

Avoid allocation under idr_lock, to prevent deadlock against the
job_free() path (which runs on same thread as job_run(), which makes
it also part of the fence-signaling path.
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Patchwork: https://patchwork.freedesktop.org/patch/527847/
Link: https://lore.kernel.org/r/20230320144356.803762-12-robdclark@gmail.com
parent e4f020c6
...@@ -882,6 +882,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -882,6 +882,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
submit->nr_cmds = i; submit->nr_cmds = i;
idr_preload(GFP_KERNEL);
spin_lock(&queue->idr_lock); spin_lock(&queue->idr_lock);
/* /*
...@@ -893,6 +895,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -893,6 +895,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) && if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) &&
idr_find(&queue->fence_idr, args->fence)) { idr_find(&queue->fence_idr, args->fence)) {
spin_unlock(&queue->idr_lock); spin_unlock(&queue->idr_lock);
idr_preload_end();
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
...@@ -910,7 +913,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -910,7 +913,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
submit->fence_id = args->fence; submit->fence_id = args->fence;
ret = idr_alloc_u32(&queue->fence_idr, submit->user_fence, ret = idr_alloc_u32(&queue->fence_idr, submit->user_fence,
&submit->fence_id, submit->fence_id, &submit->fence_id, submit->fence_id,
GFP_KERNEL); GFP_NOWAIT);
/* /*
* We've already validated that the fence_id slot is valid, * We've already validated that the fence_id slot is valid,
* so if idr_alloc_u32 failed, it is a kernel bug * so if idr_alloc_u32 failed, it is a kernel bug
...@@ -923,10 +926,11 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -923,10 +926,11 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
*/ */
submit->fence_id = idr_alloc_cyclic(&queue->fence_idr, submit->fence_id = idr_alloc_cyclic(&queue->fence_idr,
submit->user_fence, 1, submit->user_fence, 1,
INT_MAX, GFP_KERNEL); INT_MAX, GFP_NOWAIT);
} }
spin_unlock(&queue->idr_lock); spin_unlock(&queue->idr_lock);
idr_preload_end();
if (submit->fence_id < 0) { if (submit->fence_id < 0) {
ret = submit->fence_id; ret = submit->fence_id;
......
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