Skip to content

Commit

Permalink
drm/qxl: fix lockdep issue in qxl_alloc_release_reserved
Browse files Browse the repository at this point in the history
Call qxl_bo_unpin (which does a reservation) without holding the
release_mutex lock.  Fixes lockdep (correctly) warning on a possible
deadlock.

Fixes: e8dd350 ("drm/qxl: unpin release objects")
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: http://patchwork.freedesktop.org/patch/msgid/20210217123213.2199186-5-kraxel@redhat.com
(cherry picked from commit 19089b7)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
  • Loading branch information
kraxel authored and mlankhorst committed Mar 11, 2021
1 parent e8dd350 commit e998d3c
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions drivers/gpu/drm/qxl/qxl_release.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
int type, struct qxl_release **release,
struct qxl_bo **rbo)
{
struct qxl_bo *bo;
struct qxl_bo *bo, *free_bo = NULL;
int idr_ret;
int ret = 0;
union qxl_release_info *info;
Expand All @@ -347,15 +347,18 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,

mutex_lock(&qdev->release_mutex);
if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) {
qxl_bo_unpin(qdev->current_release_bo[cur_idx]);
qxl_bo_unref(&qdev->current_release_bo[cur_idx]);
free_bo = qdev->current_release_bo[cur_idx];
qdev->current_release_bo_offset[cur_idx] = 0;
qdev->current_release_bo[cur_idx] = NULL;
}
if (!qdev->current_release_bo[cur_idx]) {
ret = qxl_release_bo_alloc(qdev, &qdev->current_release_bo[cur_idx]);
if (ret) {
mutex_unlock(&qdev->release_mutex);
if (free_bo) {
qxl_bo_unpin(free_bo);
qxl_bo_unref(&free_bo);
}
qxl_release_free(qdev, *release);
return ret;
}
Expand All @@ -371,6 +374,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
*rbo = bo;

mutex_unlock(&qdev->release_mutex);
if (free_bo) {
qxl_bo_unpin(free_bo);
qxl_bo_unref(&free_bo);
}

ret = qxl_release_list_add(*release, bo);
qxl_bo_unref(&bo);
Expand Down

0 comments on commit e998d3c

Please sign in to comment.