Commit e998d3c8 authored by Gerd Hoffmann's avatar Gerd Hoffmann Committed by Maarten Lankhorst
Browse files

drm/qxl: fix lockdep issue in qxl_alloc_release_reserved



Call qxl_bo_unpin (which does a reservation) without holding the
release_mutex lock.  Fixes lockdep (correctly) warning on a possible
deadlock.

Fixes: e8dd3506 ("drm/qxl: unpin release objects")
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Link: http://patchwork.freedesktop.org/patch/msgid/20210217123213.2199186-5-kraxel@redhat.com


(cherry picked from commit 19089b76)
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
parent e8dd3506
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -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;
@@ -347,8 +347,7 @@ 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;
	}
@@ -356,6 +355,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
		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;
		}
@@ -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);