The patch titled Subject: pm / runtime: introduce pm_runtime_set_memalloc_noio() has been added to the -mm tree. Its filename is pm-runtime-introduce-pm_runtime_set_memalloc_noio.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Ming Lei <ming.lei@xxxxxxxxxxxxx> Subject: pm / runtime: introduce pm_runtime_set_memalloc_noio() Introduce the flag 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. Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxxxxx> Cc: Minchan Kim <minchan@xxxxxxxxxx> Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Cc: Oliver Neukum <oneukum@xxxxxxx> Cc: Jiri Kosina <jiri.kosina@xxxxxxxx> Cc: Mel Gorman <mel@xxxxxxxxx> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: "Rafael J. Wysocki" <rjw@xxxxxxx> Cc: Greg KH <greg@xxxxxxxxx> Cc: Jens Axboe <axboe@xxxxxxxxx> Cc: "David S. Miller" <davem@xxxxxxxxxxxxx> Cc: Eric Dumazet <eric.dumazet@xxxxxxxxx> Cc: David Decotigny <david.decotigny@xxxxxxxxxx> Cc: Tom Herbert <therbert@xxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- drivers/base/power/runtime.c | 70 +++++++++++++++++++++++++++++++++ include/linux/pm.h | 1 include/linux/pm_runtime.h | 3 + 3 files changed, 74 insertions(+) diff -puN drivers/base/power/runtime.c~pm-runtime-introduce-pm_runtime_set_memalloc_noio drivers/base/power/runtime.c --- a/drivers/base/power/runtime.c~pm-runtime-introduce-pm_runtime_set_memalloc_noio +++ a/drivers/base/power/runtime.c @@ -124,6 +124,76 @@ unsigned long pm_runtime_autosuspend_exp } 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 -puN include/linux/pm.h~pm-runtime-introduce-pm_runtime_set_memalloc_noio include/linux/pm.h --- a/include/linux/pm.h~pm-runtime-introduce-pm_runtime_set_memalloc_noio +++ a/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 -puN include/linux/pm_runtime.h~pm-runtime-introduce-pm_runtime_set_memalloc_noio include/linux/pm_runtime.h --- a/include/linux/pm_runtime.h~pm-runtime-introduce-pm_runtime_set_memalloc_noio +++ a/include/linux/pm_runtime.h @@ -47,6 +47,7 @@ extern void pm_runtime_set_autosuspend_d 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_autosu 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 */ _ Patches currently in -mm which might be from ming.lei@xxxxxxxxxxxxx are origin.patch linux-next.patch mm-teach-mm-by-current-context-info-to-not-do-i-o-during-memory-allocation.patch pm-runtime-introduce-pm_runtime_set_memalloc_noio.patch block-genhdc-apply-pm_runtime_set_memalloc_noio-on-block-devices.patch net-core-apply-pm_runtime_set_memalloc_noio-on-network-devices.patch pm-runtime-force-memory-allocation-with-no-i-o-during-runtime-pm-callbcack.patch usb-forbid-memory-allocation-with-i-o-during-bus-reset.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html