* [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O
@ 2013-01-05 2:25 Ming Lei
2013-01-05 2:25 ` [PATCH v7 1/6] mm: teach mm by current context info to not do I/O during memory allocation Ming Lei
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-05 2:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
Cc: Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm, Alan Stern,
Oliver Neukum, Minchan Kim, Rafael J. Wysocki, Jens Axboe,
David S. Miller
Hi,
This patchset try to solve one deadlock problem which might be caused
by memory allocation with block I/O during runtime PM and block device
error handling path. Traditionly, the problem is addressed by passing
GFP_NOIO statically to mm, but that is not a effective solution, see
detailed description in patch 1's commit log.
This patch set introduces one process flag and trys to fix the deadlock
problem on block device/network device during runtime PM or usb bus reset.
The 1st one is the change on include/sched.h and mm.
The 2nd patch introduces the flag of memalloc_noio on 'dev_pm_info',
and pm_runtime_set_memalloc_noio(), so that PM Core can teach mm to not
allocate mm with GFP_IO during the runtime_resume callback only on
device with the flag set.
The following 2 patches apply the introduced pm_runtime_set_memalloc_noio()
to mark all devices as memalloc_noio_resume in the path from the block or
network device to the root device in device tree.
The last 2 patches are applied again PM and USB subsystem to demonstrate
how to use the introduced mechanism to fix the deadlock problem.
Andrew, could you queue these patches into your tree since V6 fixes all
your concerns and looks no one objects these patches?
Change logs:
V7:
- rebase on v3.8-rc2-next-20130104
- move memalloc_noio_save/memalloc_noio_restore into
rpm_callback to avoid code duplication, as suggested
by Rafael
- optimize on pm_runtime_set_memalloc_noio(true)
- fix type of 'flags' in memalloc_noio_save()/memalloc_noio_restore()
V6:
- fix one compile failure(1/6), and only one line change
V5:
- don't clear GFP_FS
- coding style fix
- add comments
- see details in individual change logs
V4:
- patches from the 2nd to the 6th changed
- call pm_runtime_set_memalloc_noio() after device_add() as pointed
by Alan
- set PF_MEMALLOC_NOIO during runtime_suspend()
V3:
- patch 2/6 and 5/6 changed, see their commit log
- remove RFC from title since several guys have expressed that
it is a reasonable solution
V2:
- remove changes on 'may_writepage' and 'may_swap'(1/6)
- unset GFP_IOFS in try_to_free_pages() path(1/6)
- introduce pm_runtime_set_memalloc_noio()
- only apply the meachnism on block/network device and its ancestors
for runtime resume context
V1:
- take Minchan's change to avoid the check in alloc_page hot path
- change the helpers' style into save/restore as suggested by Alan
- memory allocation with no io in usb bus reset path for all devices
as suggested by Greg and Oliver
block/genhd.c | 10 +++++
drivers/base/power/runtime.c | 89 +++++++++++++++++++++++++++++++++++++++++-
drivers/usb/core/hub.c | 13 ++++++
include/linux/pm.h | 1 +
include/linux/pm_runtime.h | 3 ++
include/linux/sched.h | 22 +++++++++++
mm/page_alloc.c | 9 ++++-
mm/vmscan.c | 4 +-
net/core/net-sysfs.c | 5 +++
9 files changed, 152 insertions(+), 4 deletions(-)
Thanks,
--
Ming Lei
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v7 1/6] mm: teach mm by current context info to not do I/O during memory allocation
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
@ 2013-01-05 2:25 ` Ming Lei
2013-01-05 2:25 ` [PATCH v7 2/6] PM / Runtime: introduce pm_runtime_set_memalloc_noio() Ming Lei
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-05 2:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
Cc: Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm, Alan Stern,
Oliver Neukum, Minchan Kim, Rafael J. Wysocki, Jens Axboe,
David S. Miller, Ming Lei, Jiri Kosina, Mel Gorman,
KAMEZAWA Hiroyuki, Michal Hocko, Ingo Molnar, Peter Zijlstra
This patch introduces PF_MEMALLOC_NOIO on process flag('flags' field of
'struct task_struct'), so that the flag can be set by one task
to avoid doing I/O inside memory allocation in the task's context.
The patch trys to solve one deadlock problem caused by block device,
and the problem may happen at least in the below situations:
- during block device runtime resume, if memory allocation with
GFP_KERNEL is called inside runtime resume callback of any one
of its ancestors(or the block device itself), the deadlock may be
triggered inside the memory allocation since it might not complete
until the block device becomes active and the involed page I/O finishes.
The situation is pointed out first by Alan Stern. It is not a good
approach to convert all GFP_KERNEL[1] in the path into GFP_NOIO because
several subsystems may be involved(for example, PCI, USB and SCSI may
be involved for usb mass stoarage device, network devices involved too
in the iSCSI case)
- during block device runtime suspend, because runtime resume need
to wait for completion of concurrent runtime suspend.
- during error handling of usb mass storage deivce, USB bus reset
will be put on the device, so there shouldn't have any
memory allocation with GFP_KERNEL during USB bus reset, otherwise
the deadlock similar with above may be triggered. Unfortunately, any
usb device may include one mass storage interface in theory, so it
requires all usb interface drivers to handle the situation. In fact,
most usb drivers don't know how to handle bus reset on the device
and don't provide .pre_set() and .post_reset() callback at all, so
USB core has to unbind and bind driver for these devices. So it
is still not practical to resort to GFP_NOIO for solving the problem.
Also the introduced solution can be used by block subsystem or block
drivers too, for example, set the PF_MEMALLOC_NOIO flag before doing
actual I/O transfer.
It is not a good idea to convert all these GFP_KERNEL in the
affected path into GFP_NOIO because these functions doing that may be
implemented as library and will be called in many other contexts.
In fact, memalloc_noio_flags() can convert some of current static GFP_NOIO
allocation into GFP_KERNEL back in other non-affected contexts, at least
almost all GFP_NOIO in USB subsystem can be converted into GFP_KERNEL
after applying the approach and make allocation with GFP_NOIO
only happen in runtime resume/bus reset/block I/O transfer contexts
generally.
[1], several GFP_KERNEL allocation examples in runtime resume path
- pci subsystem
acpi_os_allocate
<-acpi_ut_allocate
<-ACPI_ALLOCATE_ZEROED
<-acpi_evaluate_object
<-__acpi_bus_set_power
<-acpi_bus_set_power
<-acpi_pci_set_power_state
<-platform_pci_set_power_state
<-pci_platform_power_transition
<-__pci_complete_power_transition
<-pci_set_power_state
<-pci_restore_standard_config
<-pci_pm_runtime_resume
- usb subsystem
usb_get_status
<-finish_port_resume
<-usb_port_resume
<-generic_resume
<-usb_resume_device
<-usb_resume_both
<-usb_runtime_resume
- some individual usb drivers
usblp, uvc, gspca, most of dvb-usb-v2 media drivers, cpia2, az6007, ....
That is just what I have found. Unfortunately, this allocation can
only be found by human being now, and there should be many not found
since any function in the resume path(call tree) may allocate memory
with GFP_KERNEL.
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Jiri Kosina <jiri.kosina@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
--
v7:
- fix type of 'flags' in memalloc_noio_save()/memalloc_noio_restore()
- rebase on v3.8-rc2-next-20130104
v6:
- replace GFP_IO with __GFP_IO to fix compile failure
v5:
- use inline instead of macro to define memalloc_noio_*
- replace memalloc_noio() with memalloc_noio_flags() to
make code neater
- don't clear GFP_FS because no GFP_IO means
that allocation won't enter device driver as pointed by
Andrew Morton
v4:
- fix comment
v3:
- no change
v2:
- remove changes on 'may_writepage' and 'may_swap' because that
isn't related with the patchset, and can't introduce I/O in
allocation path if GFP_IOFS is unset, so handing 'may_swap'
and may_writepage on GFP_NOIO or GFP_NOFS should be a
mm internal thing, and let mm guys deal with that, :-).
Looks clearing the two may_XXX flag only excludes dirty pages
and anon pages for relaiming, and the behaviour should be decided
by GFP FLAG, IMO.
- unset GFP_IOFS in try_to_free_pages() path since
alloc_page_buffers()
and dma_alloc_from_contiguous may drop into the path, as
pointed by KAMEZAWA Hiroyuki
v1:
- take Minchan's change to avoid the check in alloc_page hot
path
- change the helpers' style into save/restore as suggested by
Alan Stern
---
include/linux/sched.h | 22 ++++++++++++++++++++++
mm/page_alloc.c | 9 ++++++++-
mm/vmscan.c | 4 ++--
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0df4a9d..b35ae0e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -51,6 +51,7 @@ struct sched_param {
#include <linux/cred.h>
#include <linux/llist.h>
#include <linux/uidgid.h>
+#include <linux/gfp.h>
#include <asm/processor.h>
@@ -1814,6 +1815,7 @@ extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut,
#define PF_FROZEN 0x00010000 /* frozen for system suspend */
#define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */
#define PF_KSWAPD 0x00040000 /* I am kswapd */
+#define PF_MEMALLOC_NOIO 0x00080000 /* Allocating memory without IO involved */
#define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */
#define PF_KTHREAD 0x00200000 /* I am a kernel thread */
#define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */
@@ -1851,6 +1853,26 @@ extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut,
#define tsk_used_math(p) ((p)->flags & PF_USED_MATH)
#define used_math() tsk_used_math(current)
+/* __GFP_IO isn't allowed if PF_MEMALLOC_NOIO is set in current->flags */
+static inline gfp_t memalloc_noio_flags(gfp_t flags)
+{
+ if (unlikely(current->flags & PF_MEMALLOC_NOIO))
+ flags &= ~__GFP_IO;
+ return flags;
+}
+
+static inline unsigned int memalloc_noio_save(void)
+{
+ unsigned int flags = current->flags & PF_MEMALLOC_NOIO;
+ current->flags |= PF_MEMALLOC_NOIO;
+ return flags;
+}
+
+static inline void memalloc_noio_restore(unsigned int flags)
+{
+ current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags;
+}
+
/*
* task->jobctl flags
*/
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 500dc7a..b86f27e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2629,10 +2629,17 @@ retry_cpuset:
page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,
zonelist, high_zoneidx, alloc_flags,
preferred_zone, migratetype);
- if (unlikely(!page))
+ if (unlikely(!page)) {
+ /*
+ * Runtime PM, block IO and its error handling path
+ * can deadlock because I/O on the device might not
+ * complete.
+ */
+ gfp_mask = memalloc_noio_flags(gfp_mask);
page = __alloc_pages_slowpath(gfp_mask, order,
zonelist, high_zoneidx, nodemask,
preferred_zone, migratetype);
+ }
trace_mm_page_alloc(page, order, gfp_mask, migratetype);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 292f50a..9f97f44 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2353,7 +2353,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
{
unsigned long nr_reclaimed;
struct scan_control sc = {
- .gfp_mask = gfp_mask,
+ .gfp_mask = (gfp_mask = memalloc_noio_flags(gfp_mask)),
.may_writepage = !laptop_mode,
.nr_to_reclaim = SWAP_CLUSTER_MAX,
.may_unmap = 1,
@@ -3334,7 +3334,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
.may_unmap = !!(zone_reclaim_mode & RECLAIM_SWAP),
.may_swap = 1,
.nr_to_reclaim = max(nr_pages, SWAP_CLUSTER_MAX),
- .gfp_mask = gfp_mask,
+ .gfp_mask = (gfp_mask = memalloc_noio_flags(gfp_mask)),
.order = order,
.priority = ZONE_RECLAIM_PRIORITY,
};
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 2/6] PM / Runtime: introduce pm_runtime_set_memalloc_noio()
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
2013-01-05 2:25 ` [PATCH v7 1/6] mm: teach mm by current context info to not do I/O during memory allocation Ming Lei
@ 2013-01-05 2:25 ` Ming Lei
2013-01-05 2:25 ` [PATCH v7 3/6] block/genhd.c: apply pm_runtime_set_memalloc_noio on block devices Ming Lei
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-05 2:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
Cc: Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm, Alan Stern,
Oliver Neukum, Minchan Kim, Rafael J. Wysocki, Jens Axboe,
David S. Miller, Ming Lei
The patch introduces the flag of memalloc_noio in 'struct dev_pm_info'
to help PM core to teach mm not allocating memory with GFP_KERNEL
flag for avoiding probable deadlock.
As explained in the comment, any GFP_KERNEL allocation inside
runtime_resume() or runtime_suspend() on any one of device in
the path from one block or network device to the root device
in the device tree may cause deadlock, the introduced
pm_runtime_set_memalloc_noio() sets or clears the flag on
device in the path recursively.
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
--
v7:
- optimize on pm_runtime_set_memalloc_noio(true)
v5:
- fix code style error
- add comment on clear the device memalloc_noio flag
v4:
- rename memalloc_noio_resume as memalloc_noio
- remove pm_runtime_get_memalloc_noio()
- add comments on pm_runtime_set_memalloc_noio
v3:
- introduce pm_runtime_get_memalloc_noio()
- hold one global lock on pm_runtime_set_memalloc_noio
- hold device power lock when accessing memalloc_noio_resume
flag suggested by Alan Stern
- implement pm_runtime_set_memalloc_noio without recursion
suggested by Alan Stern
v2:
- introduce pm_runtime_set_memalloc_noio()
---
drivers/base/power/runtime.c | 70 ++++++++++++++++++++++++++++++++++++++++++
include/linux/pm.h | 1 +
include/linux/pm_runtime.h | 3 ++
3 files changed, 74 insertions(+)
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 3148b10..cd92e1c 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -124,6 +124,76 @@ unsigned long pm_runtime_autosuspend_expiration(struct device *dev)
}
EXPORT_SYMBOL_GPL(pm_runtime_autosuspend_expiration);
+static int dev_memalloc_noio(struct device *dev, void *data)
+{
+ return dev->power.memalloc_noio;
+}
+
+/*
+ * pm_runtime_set_memalloc_noio - Set a device's memalloc_noio flag.
+ * @dev: Device to handle.
+ * @enable: True for setting the flag and False for clearing the flag.
+ *
+ * Set the flag for all devices in the path from the device to the
+ * root device in the device tree if @enable is true, otherwise clear
+ * the flag for devices in the path whose siblings don't set the flag.
+ *
+ * The function should only be called by block device, or network
+ * device driver for solving the deadlock problem during runtime
+ * resume/suspend:
+ *
+ * If memory allocation with GFP_KERNEL is called inside runtime
+ * resume/suspend callback of any one of its ancestors(or the
+ * block device itself), the deadlock may be triggered inside the
+ * memory allocation since it might not complete until the block
+ * device becomes active and the involed page I/O finishes. The
+ * situation is pointed out first by Alan Stern. Network device
+ * are involved in iSCSI kind of situation.
+ *
+ * The lock of dev_hotplug_mutex is held in the function for handling
+ * hotplug race because pm_runtime_set_memalloc_noio() may be called
+ * in async probe().
+ *
+ * The function should be called between device_add() and device_del()
+ * on the affected device(block/network device).
+ */
+void pm_runtime_set_memalloc_noio(struct device *dev, bool enable)
+{
+ static DEFINE_MUTEX(dev_hotplug_mutex);
+
+ mutex_lock(&dev_hotplug_mutex);
+ for (;;) {
+ bool enabled;
+
+ /* hold power lock since bitfield is not SMP-safe. */
+ spin_lock_irq(&dev->power.lock);
+ enabled = dev->power.memalloc_noio;
+ dev->power.memalloc_noio = enable;
+ spin_unlock_irq(&dev->power.lock);
+
+ /*
+ * not need to enable ancestors any more if the device
+ * has been enabled.
+ */
+ if (enabled && enable)
+ break;
+
+ dev = dev->parent;
+
+ /*
+ * clear flag of the parent device only if all the
+ * children don't set the flag because ancestor's
+ * flag was set by any one of the descendants.
+ */
+ if (!dev || (!enable &&
+ device_for_each_child(dev, NULL,
+ dev_memalloc_noio)))
+ break;
+ }
+ mutex_unlock(&dev_hotplug_mutex);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_set_memalloc_noio);
+
/**
* rpm_check_suspend_allowed - Test whether a device may be suspended.
* @dev: Device to test.
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 03d7bb1..1a8a69d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -538,6 +538,7 @@ struct dev_pm_info {
unsigned int irq_safe:1;
unsigned int use_autosuspend:1;
unsigned int timer_autosuspends:1;
+ unsigned int memalloc_noio:1;
enum rpm_request request;
enum rpm_status runtime_status;
int runtime_error;
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index f271860..775e063 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -47,6 +47,7 @@ extern void pm_runtime_set_autosuspend_delay(struct device *dev, int delay);
extern unsigned long pm_runtime_autosuspend_expiration(struct device *dev);
extern void pm_runtime_update_max_time_suspended(struct device *dev,
s64 delta_ns);
+extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable);
static inline bool pm_children_suspended(struct device *dev)
{
@@ -149,6 +150,8 @@ static inline void pm_runtime_set_autosuspend_delay(struct device *dev,
int delay) {}
static inline unsigned long pm_runtime_autosuspend_expiration(
struct device *dev) { return 0; }
+static inline void pm_runtime_set_memalloc_noio(struct device *dev,
+ bool enable){}
#endif /* !CONFIG_PM_RUNTIME */
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 3/6] block/genhd.c: apply pm_runtime_set_memalloc_noio on block devices
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
2013-01-05 2:25 ` [PATCH v7 1/6] mm: teach mm by current context info to not do I/O during memory allocation Ming Lei
2013-01-05 2:25 ` [PATCH v7 2/6] PM / Runtime: introduce pm_runtime_set_memalloc_noio() Ming Lei
@ 2013-01-05 2:25 ` Ming Lei
2013-01-05 2:25 ` [PATCH v7 4/6] net/core: apply pm_runtime_set_memalloc_noio on network devices Ming Lei
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-05 2:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
Cc: Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm, Alan Stern,
Oliver Neukum, Minchan Kim, Rafael J. Wysocki, Jens Axboe,
David S. Miller, Ming Lei
This patch applyes the introduced pm_runtime_set_memalloc_noio on
block device so that PM core will teach mm to not allocate memory with
GFP_IOFS when calling the runtime_resume and runtime_suspend callback
for block devices and its ancestors.
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
--
v5:
- fix code style and one typo
v4:
- call pm_runtime_set_memalloc_noio(ddev, true) after device_add
---
block/genhd.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/block/genhd.c b/block/genhd.c
index 4125beb..2eb64a3 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -18,6 +18,7 @@
#include <linux/mutex.h>
#include <linux/idr.h>
#include <linux/log2.h>
+#include <linux/pm_runtime.h>
#include "blk.h"
@@ -534,6 +535,14 @@ static void register_disk(struct gendisk *disk)
return;
}
}
+
+ /*
+ * avoid probable deadlock caused by allocating memory with
+ * GFP_KERNEL in runtime_resume callback of its all ancestor
+ * devices
+ */
+ pm_runtime_set_memalloc_noio(ddev, true);
+
disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
@@ -663,6 +672,7 @@ void del_gendisk(struct gendisk *disk)
disk->driverfs_dev = NULL;
if (!sysfs_deprecated)
sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
+ pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
device_del(disk_to_dev(disk));
}
EXPORT_SYMBOL(del_gendisk);
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 4/6] net/core: apply pm_runtime_set_memalloc_noio on network devices
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
` (2 preceding siblings ...)
2013-01-05 2:25 ` [PATCH v7 3/6] block/genhd.c: apply pm_runtime_set_memalloc_noio on block devices Ming Lei
@ 2013-01-05 2:25 ` Ming Lei
2013-01-05 2:25 ` [PATCH v7 5/6] PM / Runtime: force memory allocation with no I/O during Runtime PM callbcack Ming Lei
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-05 2:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
Cc: Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm, Alan Stern,
Oliver Neukum, Minchan Kim, Rafael J. Wysocki, Jens Axboe,
David S. Miller, Ming Lei, Eric Dumazet, David Decotigny,
Tom Herbert, Ingo Molnar
Deadlock might be caused by allocating memory with GFP_KERNEL in
runtime_resume and runtime_suspend callback of network devices in
iSCSI situation, so mark network devices and its ancestor as
'memalloc_noio' with the introduced pm_runtime_set_memalloc_noio().
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: David Decotigny <david.decotigny@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
--
v7:
- rebase on v3.8-rc2-next-20130104
v4:
- call pm_runtime_set_memalloc_noio(ddev, true) after
device_add
---
net/core/net-sysfs.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 29c884a..67e00b2 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -21,6 +21,7 @@
#include <linux/vmalloc.h>
#include <linux/export.h>
#include <linux/jiffies.h>
+#include <linux/pm_runtime.h>
#include "net-sysfs.h"
@@ -1409,6 +1410,8 @@ void netdev_unregister_kobject(struct net_device * net)
remove_queue_kobjects(net);
+ pm_runtime_set_memalloc_noio(dev, false);
+
device_del(dev);
}
@@ -1453,6 +1456,8 @@ int netdev_register_kobject(struct net_device *net)
return error;
}
+ pm_runtime_set_memalloc_noio(dev, true);
+
return error;
}
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 5/6] PM / Runtime: force memory allocation with no I/O during Runtime PM callbcack
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
` (3 preceding siblings ...)
2013-01-05 2:25 ` [PATCH v7 4/6] net/core: apply pm_runtime_set_memalloc_noio on network devices Ming Lei
@ 2013-01-05 2:25 ` Ming Lei
2013-01-05 2:25 ` [PATCH v7 6/6] USB: forbid memory allocation with I/O during bus reset Ming Lei
2013-01-16 23:37 ` [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Andrew Morton
6 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-05 2:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
Cc: Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm, Alan Stern,
Oliver Neukum, Minchan Kim, Rafael J. Wysocki, Jens Axboe,
David S. Miller, Ming Lei
This patch applies the introduced memalloc_noio_save() and
memalloc_noio_restore() to force memory allocation with no I/O
during runtime_resume/runtime_suspend callback on device with
the flag of 'memalloc_noio' set.
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
--
v7:
- move memalloc_noio_save/memalloc_noio_restore into
rpm_callback to avoid code duplication, as suggested
by Rafael
v5:
- use inline memalloc_noio_save()
v4:
- runtime_suspend need this too because rpm_resume may wait for
completion of concurrent runtime_suspend, so deadlock still may
be triggered in runtime_suspend path.
---
drivers/base/power/runtime.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index cd92e1c..1244930 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -348,7 +348,24 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
if (!cb)
return -ENOSYS;
- retval = __rpm_callback(cb, dev);
+ if (dev->power.memalloc_noio) {
+ unsigned int noio_flag;
+
+ /*
+ * Deadlock might be caused if memory allocation with
+ * GFP_KERNEL happens inside runtime_suspend and
+ * runtime_resume callbacks of one block device's
+ * ancestor or the block device itself. Network
+ * device might be thought as part of iSCSI block
+ * device, so network device and its ancestor should
+ * be marked as memalloc_noio too.
+ */
+ noio_flag = memalloc_noio_save();
+ retval = __rpm_callback(cb, dev);
+ memalloc_noio_restore(noio_flag);
+ } else {
+ retval = __rpm_callback(cb, dev);
+ }
dev->power.runtime_error = retval;
return retval != -EACCES ? retval : -EIO;
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 6/6] USB: forbid memory allocation with I/O during bus reset
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
` (4 preceding siblings ...)
2013-01-05 2:25 ` [PATCH v7 5/6] PM / Runtime: force memory allocation with no I/O during Runtime PM callbcack Ming Lei
@ 2013-01-05 2:25 ` Ming Lei
2013-01-16 23:37 ` [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Andrew Morton
6 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-05 2:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
Cc: Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm, Alan Stern,
Oliver Neukum, Minchan Kim, Rafael J. Wysocki, Jens Axboe,
David S. Miller, Ming Lei
If one storage interface or usb network interface(iSCSI case)
exists in current configuration, memory allocation with
GFP_KERNEL during usb_device_reset() might trigger I/O transfer
on the storage interface itself and cause deadlock because
the 'us->dev_mutex' is held in .pre_reset() and the storage
interface can't do I/O transfer when the reset is triggered
by other interface, or the error handling can't be completed
if the reset is triggered by the storage itself(error handling path).
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
--
v5:
- use inline memalloc_noio_save()
v4:
- mark current memalloc_noio for every usb device reset
---
drivers/usb/core/hub.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a815fd2..698922e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5040,6 +5040,7 @@ int usb_reset_device(struct usb_device *udev)
{
int ret;
int i;
+ unsigned int noio_flag;
struct usb_host_config *config = udev->actconfig;
if (udev->state == USB_STATE_NOTATTACHED ||
@@ -5049,6 +5050,17 @@ int usb_reset_device(struct usb_device *udev)
return -EINVAL;
}
+ /*
+ * Don't allocate memory with GFP_KERNEL in current
+ * context to avoid possible deadlock if usb mass
+ * storage interface or usbnet interface(iSCSI case)
+ * is included in current configuration. The easist
+ * approach is to do it for every device reset,
+ * because the device 'memalloc_noio' flag may have
+ * not been set before reseting the usb device.
+ */
+ noio_flag = memalloc_noio_save();
+
/* Prevent autosuspend during the reset */
usb_autoresume_device(udev);
@@ -5093,6 +5105,7 @@ int usb_reset_device(struct usb_device *udev)
}
usb_autosuspend_device(udev);
+ memalloc_noio_restore(noio_flag);
return ret;
}
EXPORT_SYMBOL_GPL(usb_reset_device);
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
` (5 preceding siblings ...)
2013-01-05 2:25 ` [PATCH v7 6/6] USB: forbid memory allocation with I/O during bus reset Ming Lei
@ 2013-01-16 23:37 ` Andrew Morton
2013-01-17 1:28 ` Ming Lei
6 siblings, 1 reply; 12+ messages in thread
From: Andrew Morton @ 2013-01-16 23:37 UTC (permalink / raw)
To: Ming Lei
Cc: linux-kernel, Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm,
Alan Stern, Oliver Neukum, Minchan Kim, Rafael J. Wysocki,
Jens Axboe, David S. Miller
On Sat, 5 Jan 2013 10:25:38 +0800
Ming Lei <ming.lei@canonical.com> wrote:
> This patchset try to solve one deadlock problem which might be caused
> by memory allocation with block I/O during runtime PM and block device
> error handling path. Traditionly, the problem is addressed by passing
> GFP_NOIO statically to mm, but that is not a effective solution, see
> detailed description in patch 1's commit log.
>
> This patch set introduces one process flag and trys to fix the deadlock
> problem on block device/network device during runtime PM or usb bus reset.
The patchset doesn't look like the worst thing I've ever applied ;)
One thing I'm wondering: during suspend and resume, why are GFP_KERNEL
allocation attempts even getting down to the device layer? Presumably
the page scanner is encountering dirty pagecache or dirty swapcache
pages?
If so, I wonder if we could avoid the whole problem by appropriately
syncing all dirty memory back to storage before starting to turn devices
off?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O
2013-01-16 23:37 ` [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Andrew Morton
@ 2013-01-17 1:28 ` Ming Lei
2013-01-17 9:44 ` Oliver Neukum
2013-01-17 21:57 ` Andrew Morton
0 siblings, 2 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-17 1:28 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm,
Alan Stern, Oliver Neukum, Minchan Kim, Rafael J. Wysocki,
Jens Axboe, David S. Miller
On Thu, Jan 17, 2013 at 7:37 AM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Sat, 5 Jan 2013 10:25:38 +0800
> Ming Lei <ming.lei@canonical.com> wrote:
>
>> This patchset try to solve one deadlock problem which might be caused
>> by memory allocation with block I/O during runtime PM and block device
>> error handling path. Traditionly, the problem is addressed by passing
>> GFP_NOIO statically to mm, but that is not a effective solution, see
>> detailed description in patch 1's commit log.
>>
>> This patch set introduces one process flag and trys to fix the deadlock
>> problem on block device/network device during runtime PM or usb bus reset.
>
> The patchset doesn't look like the worst thing I've ever applied ;)
>
> One thing I'm wondering: during suspend and resume, why are GFP_KERNEL
> allocation attempts even getting down to the device layer? Presumably
> the page scanner is encountering dirty pagecache or dirty swapcache
> pages?
>
> If so, I wonder if we could avoid the whole problem by appropriately
> syncing all dirty memory back to storage before starting to turn devices
> off?
The patchset is to address the probable deadlock problem by GFP_KERNEL
during runtime suspend/resume which is per block/network device. I am
wondering if syncing all dirty memory is suitable or necessary during
per-storage/network device runtime resume/suspend:
- sys_sync is very slow and runtime pm operation is frequent
- it is not efficient because only sync dirty memory against the affected
device is needed in theory and not necessary to sync all
- we still need some synchronization to avoid accessing the storage
between sys_sync and device suspend, just like system sleep case,
pm_restrict_gfp_mask is needed even sys_sync has been done
inside enter_state().
So looks the approach in the patch is simpler and more efficient, :-)
Also, with the patchset, we can avoid many GFP_NOIO allocation
which is fragile and not easy to use.
Thanks,
--
Ming Lei
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O
2013-01-17 1:28 ` Ming Lei
@ 2013-01-17 9:44 ` Oliver Neukum
2013-01-17 21:57 ` Andrew Morton
1 sibling, 0 replies; 12+ messages in thread
From: Oliver Neukum @ 2013-01-17 9:44 UTC (permalink / raw)
To: Ming Lei
Cc: Andrew Morton, linux-kernel, Greg Kroah-Hartman, linux-usb,
linux-pm, linux-mm, Alan Stern, Minchan Kim, Rafael J. Wysocki,
Jens Axboe, David S. Miller
On Thursday 17 January 2013 09:28:14 Ming Lei wrote:
> - we still need some synchronization to avoid accessing the storage
> between sys_sync and device suspend, just like system sleep case,
> pm_restrict_gfp_mask is needed even sys_sync has been done
> inside enter_state().
>
> So looks the approach in the patch is simpler and more efficient,
Even worse. The memory may be needed to resume and the reason
we need to resume may be that we need to write out memory. And
there is no way to make sure we don't dirty memory unless user space
is frozen, so it is either this approach, or GFP_NOIO in the whole resume
code path.
Regards
Oliver
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O
2013-01-17 1:28 ` Ming Lei
2013-01-17 9:44 ` Oliver Neukum
@ 2013-01-17 21:57 ` Andrew Morton
2013-01-18 10:22 ` Ming Lei
1 sibling, 1 reply; 12+ messages in thread
From: Andrew Morton @ 2013-01-17 21:57 UTC (permalink / raw)
To: Ming Lei
Cc: linux-kernel, Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm,
Alan Stern, Oliver Neukum, Minchan Kim, Rafael J. Wysocki,
Jens Axboe, David S. Miller
On Thu, 17 Jan 2013 09:28:14 +0800
Ming Lei <ming.lei@canonical.com> wrote:
> > If so, I wonder if we could avoid the whole problem by appropriately
> > syncing all dirty memory back to storage before starting to turn devices
> > off?
>
> The patchset is to address the probable deadlock problem by GFP_KERNEL
> during runtime suspend/resume which is per block/network device. I am
> wondering if syncing all dirty memory is suitable or necessary during
> per-storage/network device runtime resume/suspend:
>
> - sys_sync is very slow and runtime pm operation is frequent
>
> - it is not efficient because only sync dirty memory against the affected
> device is needed in theory and not necessary to sync all
>
> - we still need some synchronization to avoid accessing the storage
> between sys_sync and device suspend, just like system sleep case,
> pm_restrict_gfp_mask is needed even sys_sync has been done
> inside enter_state().
>
> So looks the approach in the patch is simpler and more efficient, :-)
>
> Also, with the patchset, we can avoid many GFP_NOIO allocation
> which is fragile and not easy to use.
Fair enough, thanks.
I grabbed the patches for 3.9-rc1. It is good that the page
allocator's newly-added test of current->flags is not on the fastpath.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O
2013-01-17 21:57 ` Andrew Morton
@ 2013-01-18 10:22 ` Ming Lei
0 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2013-01-18 10:22 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Greg Kroah-Hartman, linux-usb, linux-pm, linux-mm,
Alan Stern, Oliver Neukum, Minchan Kim, Rafael J. Wysocki,
Jens Axboe, David S. Miller
On Fri, Jan 18, 2013 at 5:57 AM, Andrew Morton
<akpm@linux-foundation.org> wrote:
>
> Fair enough, thanks.
>
> I grabbed the patches for 3.9-rc1. It is good that the page
> allocator's newly-added test of current->flags is not on the fastpath.
>
Andrew, great thanks, :-)
Also thank Alan, Oliver, Minchan, Rafael, Greg and other guys who
reviewed and gave suggestions on this patch set.
Thanks,
--
Ming Lei
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-01-18 10:23 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-05 2:25 [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Ming Lei
2013-01-05 2:25 ` [PATCH v7 1/6] mm: teach mm by current context info to not do I/O during memory allocation Ming Lei
2013-01-05 2:25 ` [PATCH v7 2/6] PM / Runtime: introduce pm_runtime_set_memalloc_noio() Ming Lei
2013-01-05 2:25 ` [PATCH v7 3/6] block/genhd.c: apply pm_runtime_set_memalloc_noio on block devices Ming Lei
2013-01-05 2:25 ` [PATCH v7 4/6] net/core: apply pm_runtime_set_memalloc_noio on network devices Ming Lei
2013-01-05 2:25 ` [PATCH v7 5/6] PM / Runtime: force memory allocation with no I/O during Runtime PM callbcack Ming Lei
2013-01-05 2:25 ` [PATCH v7 6/6] USB: forbid memory allocation with I/O during bus reset Ming Lei
2013-01-16 23:37 ` [PATCH v7 0/6] solve deadlock caused by memory allocation with I/O Andrew Morton
2013-01-17 1:28 ` Ming Lei
2013-01-17 9:44 ` Oliver Neukum
2013-01-17 21:57 ` Andrew Morton
2013-01-18 10:22 ` Ming Lei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).