diff options
author | Oliver Neukum <oneukum@suse.com> | 2020-09-16 21:15:44 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-09-17 08:40:56 +0200 |
commit | b85300173d027131ced9a654c506785f15cfdd6f (patch) | |
tree | 9042c615de1b31de2ea45b2bd3105fb83fd0b56a /drivers/base/core.c | |
parent | Merge 5.9-rc5 into driver-core-next (diff) | |
download | linux-b85300173d027131ced9a654c506785f15cfdd6f.tar.xz linux-b85300173d027131ced9a654c506785f15cfdd6f.zip |
driver core: force NOIO allocations during unplug
There is one overlooked situation under which a driver must not do IO to
allocate memory. You cannot do that while disconnecting a device. A
device being disconnected is no longer functional in most cases, yet IO
may fail only when the handler runs.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Link: https://lore.kernel.org/r/20200916191544.5104-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index bb5806a2bd4c..b79783454293 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -26,6 +26,7 @@ #include <linux/pm_runtime.h> #include <linux/netdevice.h> #include <linux/sched/signal.h> +#include <linux/sched/mm.h> #include <linux/sysfs.h> #include "base.h" @@ -3062,6 +3063,7 @@ void device_del(struct device *dev) struct device *parent = dev->parent; struct kobject *glue_dir = NULL; struct class_interface *class_intf; + unsigned int noio_flag; device_lock(dev); kill_device(dev); @@ -3073,6 +3075,7 @@ void device_del(struct device *dev) /* Notify clients of device removal. This call must come * before dpm_sysfs_remove(). */ + noio_flag = memalloc_noio_save(); if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DEL_DEVICE, dev); @@ -3114,6 +3117,7 @@ void device_del(struct device *dev) glue_dir = get_glue_dir(dev); kobject_del(&dev->kobj); cleanup_glue_dir(dev, glue_dir); + memalloc_noio_restore(noio_flag); put_device(parent); } EXPORT_SYMBOL_GPL(device_del); |