mm/memory_hotplug: Fix deadlock in try_online_one_block()

There is a possible scenario where the system can deadlock
itself when it is low on memory, and attempts to online
a memory block. Consider the following scenario:

 -A thread in userspace onlines a memory block through sysfs-
 state_store() /* Acquires the device_hotplug_lock */
 device_online()
 memory_subsys_online()
 memory_block_change_state()
 memory_block_action()
 online_pages()
 memory_notify(MEM_GOING_ONLINE, ...)
 online_page_ext()
 alloc_page_ext()
 __alloc_pages_nodemask(GFP_KERNEL, ...)
 /* System enters into a critically low memory state */
 out_of_memory()
 try_online_one_block() /* Invokes lock_device_hotplug() and deadlocks */

Fix deadlock by introducing and using trylock_device_hotplug()
instead of lock_device_hotplug().

Change-Id: I52bc8075ae713c50e3c381216f3616ce8366cf31
Signed-off-by: Isaac J. Manjarres <[email protected]>
This commit is contained in:
Isaac J. Manjarres 2020-07-22 13:29:42 -07:00
commit 82202b6f97
3 changed files with 8 additions and 1 deletions

View file

@ -1321,6 +1321,11 @@ int lock_device_hotplug_sysfs(void)
return restart_syscall();
}
int trylock_device_hotplug(void)
{
return mutex_trylock(&device_hotplug_lock);
}
#ifdef CONFIG_SCHED_WALT
void lock_device_hotplug_assert(void)
{