Commit 440fb4af authored by Christian König's avatar Christian König Committed by sanglipeng1
Browse files

drm/syncobj: make lockdep complain on WAIT_FOR_SUBMIT v3

stable inclusion
from stable-v5.10.211
commit 144ec5e1ce3bd238723a259c09f635b84fda423e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAF2J4

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=144ec5e1ce3bd238723a259c09f635b84fda423e



--------------------------------

[ Upstream commit 7621350c ]

DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT can't be used when we hold locks
since we are basically waiting for userspace to do something.

Holding a lock while doing so can trivial deadlock with page faults
etc...

So make lockdep complain when a driver tries to do this.

v2: Add lockdep_assert_none_held() macro.
v3: Add might_sleep() and also use lockdep_assert_none_held() in the
    IOCTL path.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patchwork.freedesktop.org/patch/414944/


Stable-dep-of: 3c43177ffb54 ("drm/syncobj: call drm_syncobj_fence_add_wait when WAIT_AVAILABLE flag is set")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarsanglipeng1 <sanglipeng1@jd.com>
parent 3c0d556d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -387,6 +387,15 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
	if (!syncobj)
		return -ENOENT;

	/* Waiting for userspace with locks help is illegal cause that can
	 * trivial deadlock with page faults for example. Make lockdep complain
	 * about it early on.
	 */
	if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
		might_sleep();
		lockdep_assert_none_held_once();
	}

	*fence = drm_syncobj_fence_get(syncobj);

	if (*fence) {
@@ -951,6 +960,9 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
	uint64_t *points;
	uint32_t signaled_count, i;

	if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)
		lockdep_assert_none_held_once();

	points = kmalloc_array(count, sizeof(*points), GFP_KERNEL);
	if (points == NULL)
		return -ENOMEM;
+5 −0
Original line number Diff line number Diff line
@@ -321,6 +321,10 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
		WARN_ON_ONCE(debug_locks && !lockdep_is_held(l));	\
	} while (0)

#define lockdep_assert_none_held_once()	do {				\
		WARN_ON_ONCE(debug_locks && current->lockdep_depth);	\
	} while (0)

#define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)

#define lockdep_pin_lock(l)	lock_pin_lock(&(l)->dep_map)
@@ -394,6 +398,7 @@ static inline void lockdep_unregister_key(struct lock_class_key *key)
#define lockdep_assert_held_write(l)	do { (void)(l); } while (0)
#define lockdep_assert_held_read(l)		do { (void)(l); } while (0)
#define lockdep_assert_held_once(l)		do { (void)(l); } while (0)
#define lockdep_assert_none_held_once()	do { } while (0)

#define lockdep_recursing(tsk)			(0)