summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Auld <matthew.auld@intel.com>2024-09-11 16:55:27 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-09-18 19:25:17 +0200
commit9d3de463e23bfb1ff1567a32b099b1b3e5286a48 (patch)
treed319a0d8bb0de2072d2a92a0dd6cc6ac14de6722
parentfc108cbc7e7ae957450c3e3f7490f5ea1b342734 (diff)
downloadlinux-9d3de463e23bfb1ff1567a32b099b1b3e5286a48.tar.gz
linux-9d3de463e23bfb1ff1567a32b099b1b3e5286a48.tar.bz2
linux-9d3de463e23bfb1ff1567a32b099b1b3e5286a48.zip
drm/xe/client: fix deadlock in show_meminfo()
commit 9bd7ff293fc84792514aeafa06c5a17f05cb5f4b upstream. 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: 0845233388f8 ("drm/xe: Implement fdinfo memory stats printing") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2727 Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911155527.178910-5-matthew.auld@intel.com (cherry picked from commit 0083b8e6f11d7662283a267d4ce7c966812ffd8a) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/xe/xe_drm_client.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c
index 08f0b7c95901..7264bd9d5331 100644
--- a/drivers/gpu/drm/xe/xe_drm_client.c
+++ b/drivers/gpu/drm/xe/xe_drm_client.c
@@ -138,6 +138,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;
@@ -157,11 +158,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;