dm: use noio when sending kobject event
commit 6958c1c640af8c3f40fa8a2eee3b5b905d95b677 upstream. kobject_uevent may allocate memory and it may be called while there are dm devices suspended. The allocation may recurse into a suspended device, causing a deadlock. We must set the noio flag when sending a uevent. The observed deadlock was reported here: https://www.redhat.com/archives/dm-devel/2020-March/msg00025.html Reported-by: Khazhismel Kumykov <khazhy@google.com> Reported-by: Tahsin Erdogan <tahsin@google.com> Reported-by: Gabriel Krisman Bertazi <krisman@collabora.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
8e5d3786da
commit
35a9af8ddb
@@ -12,6 +12,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/sched/mm.h>
|
||||||
#include <linux/sched/signal.h>
|
#include <linux/sched/signal.h>
|
||||||
#include <linux/blkpg.h>
|
#include <linux/blkpg.h>
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
@@ -2853,17 +2854,25 @@ EXPORT_SYMBOL_GPL(dm_internal_resume_fast);
|
|||||||
int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
|
int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
|
||||||
unsigned cookie)
|
unsigned cookie)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
|
unsigned noio_flag;
|
||||||
char udev_cookie[DM_COOKIE_LENGTH];
|
char udev_cookie[DM_COOKIE_LENGTH];
|
||||||
char *envp[] = { udev_cookie, NULL };
|
char *envp[] = { udev_cookie, NULL };
|
||||||
|
|
||||||
|
noio_flag = memalloc_noio_save();
|
||||||
|
|
||||||
if (!cookie)
|
if (!cookie)
|
||||||
return kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
|
r = kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
|
||||||
else {
|
else {
|
||||||
snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u",
|
snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u",
|
||||||
DM_COOKIE_ENV_VAR_NAME, cookie);
|
DM_COOKIE_ENV_VAR_NAME, cookie);
|
||||||
return kobject_uevent_env(&disk_to_dev(md->disk)->kobj,
|
r = kobject_uevent_env(&disk_to_dev(md->disk)->kobj,
|
||||||
action, envp);
|
action, envp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memalloc_noio_restore(noio_flag);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t dm_next_uevent_seq(struct mapped_device *md)
|
uint32_t dm_next_uevent_seq(struct mapped_device *md)
|
||||||
|
|||||||
Reference in New Issue
Block a user