Skip to content

Commit

Permalink
drm/syncobj: make lockdep complain on WAIT_FOR_SUBMIT v3
Browse files Browse the repository at this point in the history
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: Christian König <christian.koenig@amd.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patchwork.freedesktop.org/patch/414944/
  • Loading branch information
Christian König committed Jan 20, 2021
1 parent f987c9e commit 7621350
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
12 changes: 12 additions & 0 deletions drivers/gpu/drm/drm_syncobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
drm_syncobj_put(syncobj);

Expand Down Expand Up @@ -940,6 +949,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;
Expand Down
5 changes: 5 additions & 0 deletions include/linux/lockdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,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)
Expand Down Expand Up @@ -387,6 +391,7 @@ extern int lockdep_is_held(const void *);
#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)

Expand Down

0 comments on commit 7621350

Please sign in to comment.