Skip to content

Commit

Permalink
drm/xe/client: fix deadlock in show_meminfo()
Browse files Browse the repository at this point in the history
There is a real deadlock as well as sleeping in atomic() bug in here, if
the bo put happens to be the last ref, since bo destruction wants to
grab the same spinlock and sleeping locks.  Fix that by dropping the ref
using xe_bo_put_deferred(), and moving the final commit outside of the
lock. Dropping the lock around the put is tricky since the bo can go
out of scope and delete itself from the list, making it difficult to
navigate to the next list entry.

Fixes: 0845233 ("drm/xe: Implement fdinfo memory stats printing")
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2727
Signed-off-by: Matthew Auld <[email protected]>
Cc: Himal Prasad Ghimiray <[email protected]>
Cc: Tejas Upadhyay <[email protected]>
Cc: "Thomas Hellström" <[email protected]>
Cc: <[email protected]> # v6.8+
Reviewed-by: Matthew Brost <[email protected]>
Reviewed-by: Tejas Upadhyay <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
(cherry picked from commit 0083b8e)
Signed-off-by: Lucas De Marchi <[email protected]>
  • Loading branch information
matt-auld authored and lucasdemarchi committed Sep 18, 2024
1 parent ee06c09 commit 99b1f74
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion drivers/gpu/drm/xe/xe_drm_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
struct xe_drm_client *client;
struct drm_gem_object *obj;
struct xe_bo *bo;
LLIST_HEAD(deferred);
unsigned int id;
u32 mem_type;

Expand All @@ -215,11 +216,14 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
list_for_each_entry(bo, &client->bos_list, client_link) {
if (!kref_get_unless_zero(&bo->ttm.base.refcount))
continue;

bo_meminfo(bo, stats);
xe_bo_put(bo);
xe_bo_put_deferred(bo, &deferred);
}
spin_unlock(&client->bos_lock);

xe_bo_put_commit(&deferred);

for (mem_type = XE_PL_SYSTEM; mem_type < TTM_NUM_MEM_TYPES; ++mem_type) {
if (!xe_mem_type_to_name[mem_type])
continue;
Expand Down

0 comments on commit 99b1f74

Please sign in to comment.