summaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.com>2020-09-16 21:15:44 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-09-17 08:40:56 +0200
commitb85300173d027131ced9a654c506785f15cfdd6f (patch)
tree9042c615de1b31de2ea45b2bd3105fb83fd0b56a /drivers/base/core.c
parentMerge 5.9-rc5 into driver-core-next (diff)
downloadlinux-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.c4
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);