* [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic
@ 2011-12-06 19:23 Srivatsa S. Bhat
2011-12-06 19:24 ` [PATCH v2 2/3] PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep() Srivatsa S. Bhat
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Srivatsa S. Bhat @ 2011-12-06 19:23 UTC (permalink / raw)
To: rjw
Cc: len.brown, linux-doc, linux-pm, kexec, linux-kernel, oleg,
rdunlap, ebiederm, pavel, tj
The [un]lock_system_sleep() APIs were originally introduced to mutually
exclude memory hotplug and hibernation.
Directly using mutex_lock(&pm_mutex) to achieve mutual exclusion with
suspend or hibernation code can lead to freezing failures. However, the
APIs [un]lock_system_sleep() can be safely used to achieve the same,
without causing freezing failures.
So, since it would be beneficial to modify all the existing users of
mutex_lock(&pm_mutex) (in all parts of the kernel), so that they use these
safe APIs intead, make these APIs generic by removing the restriction that
they work only when CONFIG_HIBERNATE_CALLBACKS is set. Moreover, that
restriction didn't buy us anything anyway.
v2: Rebased on top of the patchset posted at:
https://lkml.org/lkml/2011/12/6/334
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
---
include/linux/suspend.h | 36 ++++++++++++++++--------------------
1 files changed, 16 insertions(+), 20 deletions(-)
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 906d62c..95040cc 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -332,6 +332,8 @@ static inline bool system_entering_hibernation(void) { return false; }
#define PM_RESTORE_PREPARE 0x0005 /* Going to restore a saved image */
#define PM_POST_RESTORE 0x0006 /* Restore failed */
+extern struct mutex pm_mutex;
+
#ifdef CONFIG_PM_SLEEP
void save_processor_state(void);
void restore_processor_state(void);
@@ -352,6 +354,19 @@ extern bool events_check_enabled;
extern bool pm_wakeup_pending(void);
extern bool pm_get_wakeup_count(unsigned int *count);
extern bool pm_save_wakeup_count(unsigned int count);
+
+static inline void lock_system_sleep(void)
+{
+ freezer_do_not_count();
+ mutex_lock(&pm_mutex);
+}
+
+static inline void unlock_system_sleep(void)
+{
+ mutex_unlock(&pm_mutex);
+ freezer_count();
+}
+
#else /* !CONFIG_PM_SLEEP */
static inline int register_pm_notifier(struct notifier_block *nb)
@@ -367,30 +382,11 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
#define pm_notifier(fn, pri) do { (void)(fn); } while (0)
static inline bool pm_wakeup_pending(void) { return false; }
-#endif /* !CONFIG_PM_SLEEP */
-
-extern struct mutex pm_mutex;
-#ifndef CONFIG_HIBERNATE_CALLBACKS
static inline void lock_system_sleep(void) {}
static inline void unlock_system_sleep(void) {}
-#else
-
-/* Let some subsystems like memory hotadd exclude hibernation */
-
-static inline void lock_system_sleep(void)
-{
- freezer_do_not_count();
- mutex_lock(&pm_mutex);
-}
-
-static inline void unlock_system_sleep(void)
-{
- mutex_unlock(&pm_mutex);
- freezer_count();
-}
-#endif
+#endif /* !CONFIG_PM_SLEEP */
#ifdef CONFIG_ARCH_SAVE_PAGE_KEYS
/*
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 2/3] PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep() 2011-12-06 19:23 [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic Srivatsa S. Bhat @ 2011-12-06 19:24 ` Srivatsa S. Bhat 2011-12-07 0:36 ` Simon Horman 2011-12-06 19:24 ` [PATCH v2 3/3] PM / Docs: Recommend the use of [un]lock_system_sleep() over mutex_[un]lock(&pm_mutex) Srivatsa S. Bhat 2011-12-06 22:35 ` [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic Rafael J. Wysocki 2 siblings, 1 reply; 5+ messages in thread From: Srivatsa S. Bhat @ 2011-12-06 19:24 UTC (permalink / raw) To: rjw Cc: len.brown, linux-doc, linux-pm, kexec, linux-kernel, oleg, rdunlap, ebiederm, pavel, tj Using [un]lock_system_sleep() is safer than directly using mutex_[un]lock() on 'pm_mutex', since the latter could lead to freezing failures. Hence convert all the present users of mutex_[un]lock(&pm_mutex) to use these safe APIs instead. Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> --- kernel/kexec.c | 4 ++-- kernel/power/hibernate.c | 16 ++++++++-------- kernel/power/main.c | 4 ++-- kernel/power/suspend.c | 4 ++-- kernel/power/user.c | 16 ++++++++-------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/kernel/kexec.c b/kernel/kexec.c index dc7bc08..090ee10 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1523,7 +1523,7 @@ int kernel_kexec(void) #ifdef CONFIG_KEXEC_JUMP if (kexec_image->preserve_context) { - mutex_lock(&pm_mutex); + lock_system_sleep(); pm_prepare_console(); error = freeze_processes(); if (error) { @@ -1576,7 +1576,7 @@ int kernel_kexec(void) thaw_processes(); Restore_console: pm_restore_console(); - mutex_unlock(&pm_mutex); + unlock_system_sleep(); } #endif diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 605149a..6d6d288 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -69,14 +69,14 @@ void hibernation_set_ops(const struct platform_hibernation_ops *ops) WARN_ON(1); return; } - mutex_lock(&pm_mutex); + lock_system_sleep(); hibernation_ops = ops; if (ops) hibernation_mode = HIBERNATION_PLATFORM; else if (hibernation_mode == HIBERNATION_PLATFORM) hibernation_mode = HIBERNATION_SHUTDOWN; - mutex_unlock(&pm_mutex); + unlock_system_sleep(); } static bool entering_platform_hibernation; @@ -597,7 +597,7 @@ int hibernate(void) { int error; - mutex_lock(&pm_mutex); + lock_system_sleep(); /* The snapshot device should not be opened while we're running */ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { error = -EBUSY; @@ -665,7 +665,7 @@ int hibernate(void) pm_restore_console(); atomic_inc(&snapshot_device_available); Unlock: - mutex_unlock(&pm_mutex); + unlock_system_sleep(); return error; } @@ -893,7 +893,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, p = memchr(buf, '\n', n); len = p ? p - buf : n; - mutex_lock(&pm_mutex); + lock_system_sleep(); for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) { if (len == strlen(hibernation_modes[i]) && !strncmp(buf, hibernation_modes[i], len)) { @@ -919,7 +919,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, if (!error) pr_debug("PM: Hibernation mode set to '%s'\n", hibernation_modes[mode]); - mutex_unlock(&pm_mutex); + unlock_system_sleep(); return error ? error : n; } @@ -946,9 +946,9 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, if (maj != MAJOR(res) || min != MINOR(res)) goto out; - mutex_lock(&pm_mutex); + lock_system_sleep(); swsusp_resume_device = res; - mutex_unlock(&pm_mutex); + unlock_system_sleep(); printk(KERN_INFO "PM: Starting manual resume from disk\n"); noresume = 0; software_resume(); diff --git a/kernel/power/main.c b/kernel/power/main.c index 7d36fb3..9824b41e 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -116,7 +116,7 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, p = memchr(buf, '\n', n); len = p ? p - buf : n; - mutex_lock(&pm_mutex); + lock_system_sleep(); level = TEST_FIRST; for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++) @@ -126,7 +126,7 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, break; } - mutex_unlock(&pm_mutex); + unlock_system_sleep(); return error ? error : n; } diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index d336b27..4fd51be 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -42,9 +42,9 @@ static const struct platform_suspend_ops *suspend_ops; */ void suspend_set_ops(const struct platform_suspend_ops *ops) { - mutex_lock(&pm_mutex); + lock_system_sleep(); suspend_ops = ops; - mutex_unlock(&pm_mutex); + unlock_system_sleep(); } EXPORT_SYMBOL_GPL(suspend_set_ops); diff --git a/kernel/power/user.c b/kernel/power/user.c index 06ea33d..98ade21 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -71,7 +71,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) struct snapshot_data *data; int error; - mutex_lock(&pm_mutex); + lock_system_sleep(); if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { error = -EBUSY; @@ -123,7 +123,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) data->platform_support = 0; Unlock: - mutex_unlock(&pm_mutex); + unlock_system_sleep(); return error; } @@ -132,7 +132,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) { struct snapshot_data *data; - mutex_lock(&pm_mutex); + lock_system_sleep(); swsusp_free(); free_basic_memory_bitmaps(); @@ -146,7 +146,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) PM_POST_HIBERNATION : PM_POST_RESTORE); atomic_inc(&snapshot_device_available); - mutex_unlock(&pm_mutex); + unlock_system_sleep(); return 0; } @@ -158,7 +158,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, ssize_t res; loff_t pg_offp = *offp & ~PAGE_MASK; - mutex_lock(&pm_mutex); + lock_system_sleep(); data = filp->private_data; if (!data->ready) { @@ -179,7 +179,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, *offp += res; Unlock: - mutex_unlock(&pm_mutex); + unlock_system_sleep(); return res; } @@ -191,7 +191,7 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, ssize_t res; loff_t pg_offp = *offp & ~PAGE_MASK; - mutex_lock(&pm_mutex); + lock_system_sleep(); data = filp->private_data; @@ -208,7 +208,7 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, if (res > 0) *offp += res; unlock: - mutex_unlock(&pm_mutex); + unlock_system_sleep(); return res; } _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/3] PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep() 2011-12-06 19:24 ` [PATCH v2 2/3] PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep() Srivatsa S. Bhat @ 2011-12-07 0:36 ` Simon Horman 0 siblings, 0 replies; 5+ messages in thread From: Simon Horman @ 2011-12-07 0:36 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: len.brown, linux-pm, linux-doc, kexec, linux-kernel, oleg, rjw, rdunlap, ebiederm, pavel, tj On Wed, Dec 07, 2011 at 12:54:02AM +0530, Srivatsa S. Bhat wrote: > Using [un]lock_system_sleep() is safer than directly using mutex_[un]lock() > on 'pm_mutex', since the latter could lead to freezing failures. Hence convert > all the present users of mutex_[un]lock(&pm_mutex) to use these safe APIs > instead. > > Suggested-by: Tejun Heo <tj@kernel.org> > Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> I am happy with this from a kexec point of view. Reviewed-by: Simon Horman <horms@verge.net.au> > --- > > kernel/kexec.c | 4 ++-- > kernel/power/hibernate.c | 16 ++++++++-------- > kernel/power/main.c | 4 ++-- > kernel/power/suspend.c | 4 ++-- > kernel/power/user.c | 16 ++++++++-------- > 5 files changed, 22 insertions(+), 22 deletions(-) > > diff --git a/kernel/kexec.c b/kernel/kexec.c > index dc7bc08..090ee10 100644 > --- a/kernel/kexec.c > +++ b/kernel/kexec.c > @@ -1523,7 +1523,7 @@ int kernel_kexec(void) > > #ifdef CONFIG_KEXEC_JUMP > if (kexec_image->preserve_context) { > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > pm_prepare_console(); > error = freeze_processes(); > if (error) { > @@ -1576,7 +1576,7 @@ int kernel_kexec(void) > thaw_processes(); > Restore_console: > pm_restore_console(); > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > } > #endif > > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c > index 605149a..6d6d288 100644 > --- a/kernel/power/hibernate.c > +++ b/kernel/power/hibernate.c > @@ -69,14 +69,14 @@ void hibernation_set_ops(const struct platform_hibernation_ops *ops) > WARN_ON(1); > return; > } > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > hibernation_ops = ops; > if (ops) > hibernation_mode = HIBERNATION_PLATFORM; > else if (hibernation_mode == HIBERNATION_PLATFORM) > hibernation_mode = HIBERNATION_SHUTDOWN; > > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > } > > static bool entering_platform_hibernation; > @@ -597,7 +597,7 @@ int hibernate(void) > { > int error; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > /* The snapshot device should not be opened while we're running */ > if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { > error = -EBUSY; > @@ -665,7 +665,7 @@ int hibernate(void) > pm_restore_console(); > atomic_inc(&snapshot_device_available); > Unlock: > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > return error; > } > > @@ -893,7 +893,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, > p = memchr(buf, '\n', n); > len = p ? p - buf : n; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) { > if (len == strlen(hibernation_modes[i]) > && !strncmp(buf, hibernation_modes[i], len)) { > @@ -919,7 +919,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, > if (!error) > pr_debug("PM: Hibernation mode set to '%s'\n", > hibernation_modes[mode]); > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > return error ? error : n; > } > > @@ -946,9 +946,9 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, > if (maj != MAJOR(res) || min != MINOR(res)) > goto out; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > swsusp_resume_device = res; > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > printk(KERN_INFO "PM: Starting manual resume from disk\n"); > noresume = 0; > software_resume(); > diff --git a/kernel/power/main.c b/kernel/power/main.c > index 7d36fb3..9824b41e 100644 > --- a/kernel/power/main.c > +++ b/kernel/power/main.c > @@ -116,7 +116,7 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, > p = memchr(buf, '\n', n); > len = p ? p - buf : n; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > > level = TEST_FIRST; > for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++) > @@ -126,7 +126,7 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, > break; > } > > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > > return error ? error : n; > } > diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c > index d336b27..4fd51be 100644 > --- a/kernel/power/suspend.c > +++ b/kernel/power/suspend.c > @@ -42,9 +42,9 @@ static const struct platform_suspend_ops *suspend_ops; > */ > void suspend_set_ops(const struct platform_suspend_ops *ops) > { > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > suspend_ops = ops; > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > } > EXPORT_SYMBOL_GPL(suspend_set_ops); > > diff --git a/kernel/power/user.c b/kernel/power/user.c > index 06ea33d..98ade21 100644 > --- a/kernel/power/user.c > +++ b/kernel/power/user.c > @@ -71,7 +71,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) > struct snapshot_data *data; > int error; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > > if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { > error = -EBUSY; > @@ -123,7 +123,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) > data->platform_support = 0; > > Unlock: > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > > return error; > } > @@ -132,7 +132,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) > { > struct snapshot_data *data; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > > swsusp_free(); > free_basic_memory_bitmaps(); > @@ -146,7 +146,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) > PM_POST_HIBERNATION : PM_POST_RESTORE); > atomic_inc(&snapshot_device_available); > > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > > return 0; > } > @@ -158,7 +158,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, > ssize_t res; > loff_t pg_offp = *offp & ~PAGE_MASK; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > > data = filp->private_data; > if (!data->ready) { > @@ -179,7 +179,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, > *offp += res; > > Unlock: > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > > return res; > } > @@ -191,7 +191,7 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, > ssize_t res; > loff_t pg_offp = *offp & ~PAGE_MASK; > > - mutex_lock(&pm_mutex); > + lock_system_sleep(); > > data = filp->private_data; > > @@ -208,7 +208,7 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, > if (res > 0) > *offp += res; > unlock: > - mutex_unlock(&pm_mutex); > + unlock_system_sleep(); > > return res; > } > > > _______________________________________________ > kexec mailing list > kexec@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/kexec > _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] PM / Docs: Recommend the use of [un]lock_system_sleep() over mutex_[un]lock(&pm_mutex) 2011-12-06 19:23 [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic Srivatsa S. Bhat 2011-12-06 19:24 ` [PATCH v2 2/3] PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep() Srivatsa S. Bhat @ 2011-12-06 19:24 ` Srivatsa S. Bhat 2011-12-06 22:35 ` [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic Rafael J. Wysocki 2 siblings, 0 replies; 5+ messages in thread From: Srivatsa S. Bhat @ 2011-12-06 19:24 UTC (permalink / raw) To: rjw Cc: len.brown, linux-doc, linux-pm, kexec, linux-kernel, oleg, rdunlap, ebiederm, pavel, tj Update the documentation to explain the perils of directly using mutex_[un]lock(&pm_mutex) and recommend the usage of the safe APIs [un]lock_system_sleep() instead. Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> --- Documentation/power/freezing-of-tasks.txt | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-) diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt index 3ab9fbd..6ccb68f 100644 --- a/Documentation/power/freezing-of-tasks.txt +++ b/Documentation/power/freezing-of-tasks.txt @@ -176,3 +176,28 @@ tasks, since it generally exists anyway. A driver must have all firmwares it may need in RAM before suspend() is called. If keeping them is not practical, for example due to their size, they must be requested early enough using the suspend notifier API described in notifiers.txt. + +VI. Are there any precautions to be taken to prevent freezing failures? + +Yes, there are. + +First of all, grabbing the 'pm_mutex' lock to mutually exclude a piece of code +from system-wide sleep such as suspend/hibernation is not encouraged. +If possible, that piece of code must instead hook onto the suspend/hibernation +notifiers to achieve mutual exclusion. Look at the CPU-Hotplug code +(kernel/cpu.c) for an example. + +However, if that is not feasible, and grabbing 'pm_mutex' is deemed necessary, +it is strongly discouraged to directly call mutex_[un]lock(&pm_mutex) since +that could lead to freezing failures, because if the suspend/hibernate code +successfully acquired the 'pm_mutex' lock, and hence that other entity failed +to acquire the lock, then that task would get blocked in TASK_UNINTERRUPTIBLE +state. As a consequence, the freezer would not be able to freeze that task, +leading to freezing failure. + +However, the [un]lock_system_sleep() APIs are safe to use in this scenario, +since they ask the freezer to skip freezing this task, since it is anyway +"frozen enough" as it is blocked on 'pm_mutex', which will be released +only after the entire suspend/hibernation sequence is complete. +So, to summarize, use [un]lock_system_sleep() instead of directly using +mutex_[un]lock(&pm_mutex). That would prevent freezing failures. _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic 2011-12-06 19:23 [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic Srivatsa S. Bhat 2011-12-06 19:24 ` [PATCH v2 2/3] PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep() Srivatsa S. Bhat 2011-12-06 19:24 ` [PATCH v2 3/3] PM / Docs: Recommend the use of [un]lock_system_sleep() over mutex_[un]lock(&pm_mutex) Srivatsa S. Bhat @ 2011-12-06 22:35 ` Rafael J. Wysocki 2 siblings, 0 replies; 5+ messages in thread From: Rafael J. Wysocki @ 2011-12-06 22:35 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: len.brown, linux-doc, linux-pm, kexec, linux-kernel, oleg, rdunlap, ebiederm, pavel, tj On Tuesday, December 06, 2011, Srivatsa S. Bhat wrote: > The [un]lock_system_sleep() APIs were originally introduced to mutually > exclude memory hotplug and hibernation. > > Directly using mutex_lock(&pm_mutex) to achieve mutual exclusion with > suspend or hibernation code can lead to freezing failures. However, the > APIs [un]lock_system_sleep() can be safely used to achieve the same, > without causing freezing failures. > > So, since it would be beneficial to modify all the existing users of > mutex_lock(&pm_mutex) (in all parts of the kernel), so that they use these > safe APIs intead, make these APIs generic by removing the restriction that > they work only when CONFIG_HIBERNATE_CALLBACKS is set. Moreover, that > restriction didn't buy us anything anyway. > > v2: Rebased on top of the patchset posted at: > https://lkml.org/lkml/2011/12/6/334 > > Suggested-by: Tejun Heo <tj@kernel.org> > Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> All patches in this series applied to linux-pm/linux-next. Thanks, Rafael > --- > > include/linux/suspend.h | 36 ++++++++++++++++-------------------- > 1 files changed, 16 insertions(+), 20 deletions(-) > > diff --git a/include/linux/suspend.h b/include/linux/suspend.h > index 906d62c..95040cc 100644 > --- a/include/linux/suspend.h > +++ b/include/linux/suspend.h > @@ -332,6 +332,8 @@ static inline bool system_entering_hibernation(void) { return false; } > #define PM_RESTORE_PREPARE 0x0005 /* Going to restore a saved image */ > #define PM_POST_RESTORE 0x0006 /* Restore failed */ > > +extern struct mutex pm_mutex; > + > #ifdef CONFIG_PM_SLEEP > void save_processor_state(void); > void restore_processor_state(void); > @@ -352,6 +354,19 @@ extern bool events_check_enabled; > extern bool pm_wakeup_pending(void); > extern bool pm_get_wakeup_count(unsigned int *count); > extern bool pm_save_wakeup_count(unsigned int count); > + > +static inline void lock_system_sleep(void) > +{ > + freezer_do_not_count(); > + mutex_lock(&pm_mutex); > +} > + > +static inline void unlock_system_sleep(void) > +{ > + mutex_unlock(&pm_mutex); > + freezer_count(); > +} > + > #else /* !CONFIG_PM_SLEEP */ > > static inline int register_pm_notifier(struct notifier_block *nb) > @@ -367,30 +382,11 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) > #define pm_notifier(fn, pri) do { (void)(fn); } while (0) > > static inline bool pm_wakeup_pending(void) { return false; } > -#endif /* !CONFIG_PM_SLEEP */ > - > -extern struct mutex pm_mutex; > > -#ifndef CONFIG_HIBERNATE_CALLBACKS > static inline void lock_system_sleep(void) {} > static inline void unlock_system_sleep(void) {} > > -#else > - > -/* Let some subsystems like memory hotadd exclude hibernation */ > - > -static inline void lock_system_sleep(void) > -{ > - freezer_do_not_count(); > - mutex_lock(&pm_mutex); > -} > - > -static inline void unlock_system_sleep(void) > -{ > - mutex_unlock(&pm_mutex); > - freezer_count(); > -} > -#endif > +#endif /* !CONFIG_PM_SLEEP */ > > #ifdef CONFIG_ARCH_SAVE_PAGE_KEYS > /* > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-12-07 0:36 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-12-06 19:23 [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic Srivatsa S. Bhat 2011-12-06 19:24 ` [PATCH v2 2/3] PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep() Srivatsa S. Bhat 2011-12-07 0:36 ` Simon Horman 2011-12-06 19:24 ` [PATCH v2 3/3] PM / Docs: Recommend the use of [un]lock_system_sleep() over mutex_[un]lock(&pm_mutex) Srivatsa S. Bhat 2011-12-06 22:35 ` [PATCH v2 1/3] PM / Sleep: Make [un]lock_system_sleep() generic Rafael J. Wysocki
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).