s390/debug: Fix deadlock during unregister

Unregistering an s390dbf debug area while one of the associated debugfs
files is being written to can cause a deadlock:

$ echo >.../vmur/level    $ rmmod vmur
===================================================
debugfs write
debugfs_file_get()
                          debug_unregister()
                          mutex_lock(debug_mutex)
                          debugfs_remove()
                          wait for debugfs_file_put()
debug_file_ops.write()
debug_input()
mutex_lock(debug_mutex) ==> DEADLOCK

Fix this by splitting debug_unregister() into an s390dbf and debugfs
part, and running only the s390dbf part with debug_mutex locked.

Fixes: 9372a82892 ("s390/debug: fix debug area life cycle")
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
Peter Oberparleiter 2026-08-12 09:53:19 +02:00 committed by Vasily Gorbik
parent 337bd95507
commit 445c31ac63

View File

@ -993,8 +993,8 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
mutex_unlock(&debug_mutex);
}
/* Remove debugfs entries and remove from internal list. */
static void _debug_unregister(debug_info_t *id)
/* Remove debugfs entries. */
static void _debug_unregister_debugfs(debug_info_t *id)
{
int i;
@ -1004,6 +1004,11 @@ static void _debug_unregister(debug_info_t *id)
debugfs_remove(id->debugfs_entries[i]);
}
debugfs_remove(id->debugfs_root_entry);
}
/* Remove from internal list. */
static void _debug_unregister(debug_info_t *id)
{
if (id == debug_area_first)
debug_area_first = id->next;
if (id == debug_area_last)
@ -1029,6 +1034,7 @@ void debug_unregister(debug_info_t *id)
mutex_lock(&debug_mutex);
_debug_unregister(id);
mutex_unlock(&debug_mutex);
_debug_unregister_debugfs(id);
debug_info_put(id);
}