Re: [RFC PATCH] usb: host: xhci: allow __GFP_FS in dma allocation

From: Oliver Neukum
Date: Tue May 28 2019 - 08:38:13 EST


Am Donnerstag, den 23.05.2019, 10:01 -0400 schrieb Alan Stern:
> On Wed, 22 May 2019, Oliver Neukum wrote:
>
> > On Mi, 2019-05-22 at 10:56 -0400, Alan Stern wrote:
> > > On Wed, 22 May 2019, Oliver Neukum wrote:
> > >
> > > > I agree with the problem, but I fail to see why this issue would be
> > > > specific to USB. Shouldn't this be done in the device core layer?
> > >
> > > Only for drivers that are on the block-device writeback path. The
> > > device core doesn't know which drivers these are.
> >
> > Neither does USB know. It is very hard to predict or even tell which
> > devices are block device drivers. I think we must assume that
> > any device may be affected.
>
> All right. Would you like to submit a patch?

Do you like this one?

Regards
Oliver
From 0dc9c7dfe994fc9c28a63ba283e4442c237f6989 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Tue, 28 May 2019 11:43:02 +0200
Subject: [PATCH] base: 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@xxxxxxxx>
---
drivers/base/core.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index fd7511e04e62..a7f5f45bd761 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2229,6 +2229,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;

/*
* Hold the device lock and set the "dead" flag to guarantee that
@@ -2256,6 +2257,7 @@ void device_del(struct device *dev)
device_remove_sys_dev_entry(dev);
device_remove_file(dev, &dev_attr_dev);
}
+ noio_flag = memalloc_noio_save();
if (dev->class) {
device_remove_class_symlinks(dev);

@@ -2277,6 +2279,8 @@ void device_del(struct device *dev)
device_platform_notify(dev, KOBJ_REMOVE);
device_remove_properties(dev);
device_links_purge(dev);
+ memalloc_noio_restore(noio_flag);
+

if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
--
2.16.4