Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 1/1] suspend: make sync() on suspend-to-RAM optional

36 views
Skip to first unread message

Len Brown

unread,
Jan 23, 2014, 2:20:01 AM1/23/14
to
From: Len Brown <len....@intel.com>

Linux suspend-to-RAM was unreliable when first developed,
and so sys_sync() was invoked inside the kernel at the
start of every suspend flow.

Today, many devices are invoking suspend with
high reliability and high frequency, and they don't
want to be forced to pay for sync on every suspend.

So here we make it optional.
De-select CONFIG_PM_SLEEP_SYNC to delete the call entirely.
or keep CONFIG_PM_SLEEP and you can now clear the
sys/power/sleep_sync attribte to disable the sync
from user-space.

As we have had this call for a long time,
the default remains to keep the call, and to
invoke it on every suspend.

Signed-off-by: Len Brown <len....@intel.com>
---
kernel/power/Kconfig | 8 ++++++++
kernel/power/main.c | 33 +++++++++++++++++++++++++++++++++
kernel/power/power.h | 1 +
kernel/power/suspend.c | 10 +++++++---
4 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 2fac9cc..d2927ce 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -102,6 +102,14 @@ config PM_SLEEP_SMP
depends on PM_SLEEP
select HOTPLUG_CPU

+config PM_SLEEP_SYNC
+ bool "Suspend to RAM starts with in-kernel call to sync()"
+ default y
+ depends on PM_SLEEP
+ ---help---
+ Build a call to sync() into the Linux kernel suspend to RAM flow.
+ The sync can still be skipped by clearing /sys/power/sleep_sync.
+
config PM_AUTOSLEEP
bool "Opportunistic sleep"
depends on PM_SLEEP
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 1d1bf63..1102871 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -71,6 +71,36 @@ static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,

power_attr(pm_async);

+#ifdef CONFIG_PM_SLEEP_SYNC
+
+/* If set, sync file systems at start of suspend flow */
+int pm_sleep_sync_enabled = 1;
+
+static ssize_t pm_sleep_sync_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", pm_sleep_sync_enabled);
+}
+
+static ssize_t pm_sleep_sync_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned long val;
+
+ if (kstrtoul(buf, 10, &val))
+ return -EINVAL;
+
+ if (val > 1)
+ return -EINVAL;
+
+ pm_sleep_sync_enabled = val;
+ return n;
+}
+
+power_attr(pm_sleep_sync);
+
+#endif /* CONFIG_PM_SLEEP_SYNC */
+
#ifdef CONFIG_PM_DEBUG
int pm_test_level = TEST_NONE;

@@ -592,6 +622,9 @@ static struct attribute * g[] = {
#ifdef CONFIG_PM_SLEEP
&pm_async_attr.attr,
&wakeup_count_attr.attr,
+#ifdef CONFIG_PM_SLEEP_SYNC
+ &pm_sleep_sync_attr.attr,
+#endif
#ifdef CONFIG_PM_AUTOSLEEP
&autosleep_attr.attr,
#endif
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 7d4b7ff..dca60a7 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -200,6 +200,7 @@ static inline void suspend_test_finish(const char *label) {}
#ifdef CONFIG_PM_SLEEP
/* kernel/power/main.c */
extern int pm_notifier_call_chain(unsigned long val);
+extern int pm_sleep_sync_enabled;
#endif

#ifdef CONFIG_HIGHMEM
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 62ee437..2fb2f51 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -333,9 +333,13 @@ static int enter_state(suspend_state_t state)
if (state == PM_SUSPEND_FREEZE)
freeze_begin();

- printk(KERN_INFO "PM: Syncing filesystems ... ");
- sys_sync();
- printk("done.\n");
+#ifdef CONFIG_PM_SLEEP_SYNC
+ if (pm_sleep_sync_enabled) {
+ printk(KERN_INFO "PM: Syncing filesystems ... ");
+ sys_sync();
+ printk("done.\n");
+ }
+#endif /* CONFIG_PM_SLEEP_SYNC */

pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
error = suspend_prepare(state);
--
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Zhang Rui

unread,
Jan 23, 2014, 2:30:01 AM1/23/14
to
this is actually a suspend specific feature, and it should depends on
SUSPEND instead?

thanks,
rui

Brown, Len

unread,
Jan 23, 2014, 2:50:02 AM1/23/14
to
> > + depends on PM_SLEEP
>
> this is actually a suspend specific feature, and it should depends on
> SUSPEND instead?

yup, will update.

thanks,
-Len

Srivatsa S. Bhat

unread,
Jan 23, 2014, 2:50:02 AM1/23/14
to
How about naming it as PM_SLEEP_FS_SYNC (and similarly in the sysfs files
and variable names as well). Just to avoid confusion with "synchronous/async".

Regards,
Srivatsa S. Bhat

Brown, Len

unread,
Jan 23, 2014, 3:00:01 AM1/23/14
to
> How about naming it as PM_SLEEP_FS_SYNC (and similarly in the sysfs
> files
> and variable names as well). Just to avoid confusion with
> "synchronous/async".


good point -- thanks!

Len Brown

unread,
Jan 23, 2014, 3:00:01 AM1/23/14
to
From: Len Brown <len....@intel.com>

Linux suspend-to-RAM was unreliable when first developed,
and so sys_sync() was invoked inside the kernel at the
start of every suspend flow.

Today, many devices are invoking suspend with
high reliability and high frequency, and they don't
want to be forced to pay for sync on every suspend.

So here we make it optional.
De-select CONFIG_PM_SUSPEND_SYNC to delete the call entirely.
or keep CONFIG_PM_SUSPEND_SYNC and you can now clear the
sys/power/suspend_sync attribte to disable the sync
from user-space.

As we have had this call for a long time,
the default remains to keep the call, and to
invoke it on every suspend.

Signed-off-by: Len Brown <len....@intel.com>
---
kernel/power/Kconfig | 8 ++++++++
kernel/power/main.c | 33 +++++++++++++++++++++++++++++++++
kernel/power/power.h | 1 +
kernel/power/suspend.c | 10 +++++++---
4 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 2fac9cc..61c7bd1 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -102,6 +102,14 @@ config PM_SLEEP_SMP
depends on PM_SLEEP
select HOTPLUG_CPU

+config SUSPEND_SYNC
+ bool "Suspend to RAM starts with in-kernel call to sync()"
+ default y
+ depends on SUSPEND
+ ---help---
+ Build a call to sync() into the Linux kernel suspend to RAM flow.
+ The sync can still be skipped by clearing /sys/power/suspend_sync.
+
config PM_AUTOSLEEP
bool "Opportunistic sleep"
depends on PM_SLEEP
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 1d1bf63..bd7eeeb 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -71,6 +71,36 @@ static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,

power_attr(pm_async);

+#ifdef CONFIG_SUSPEND_SYNC
+
+/* If set, sync file systems at start of suspend flow */
+int suspend_sync_enabled = 1;
+
+static ssize_t suspend_sync_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", suspend_sync_enabled);
+}
+
+static ssize_t suspend_sync_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned long val;
+
+ if (kstrtoul(buf, 10, &val))
+ return -EINVAL;
+
+ if (val > 1)
+ return -EINVAL;
+
+ suspend_sync_enabled = val;
+ return n;
+}
+
+power_attr(suspend_sync);
+
+#endif /* CONFIG_SUSPEND_SYNC */
+
#ifdef CONFIG_PM_DEBUG
int pm_test_level = TEST_NONE;

@@ -592,6 +622,9 @@ static struct attribute * g[] = {
#ifdef CONFIG_PM_SLEEP
&pm_async_attr.attr,
&wakeup_count_attr.attr,
+#ifdef CONFIG_PM_SLEEP_SYNC
+ &suspend_sync_attr.attr,
+#endif
#ifdef CONFIG_PM_AUTOSLEEP
&autosleep_attr.attr,
#endif
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 7d4b7ff..7dd66ff 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -200,6 +200,7 @@ static inline void suspend_test_finish(const char *label) {}
#ifdef CONFIG_PM_SLEEP
/* kernel/power/main.c */
extern int pm_notifier_call_chain(unsigned long val);
+extern int suspend_sync_enabled;
#endif

#ifdef CONFIG_HIGHMEM
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 62ee437..5155cb9 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -333,9 +333,13 @@ static int enter_state(suspend_state_t state)
if (state == PM_SUSPEND_FREEZE)
freeze_begin();

- printk(KERN_INFO "PM: Syncing filesystems ... ");
- sys_sync();
- printk("done.\n");
+#ifdef CONFIG_SUSPEND_SYNC
+ if (suspend_sync_enabled) {
+ printk(KERN_INFO "PM: Syncing filesystems ... ");
+ sys_sync();
+ printk("done.\n");
+ }
+#endif /* CONFIG_SUSPEND_SYNC */

pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
error = suspend_prepare(state);
--
1.8.3.2

Len Brown

unread,
Jan 23, 2014, 3:20:02 AM1/23/14
to
From: Len Brown <len....@intel.com>

Linux suspend-to-RAM was unreliable when first developed,
and so sys_sync() was invoked inside the kernel at the
start of every suspend flow.

Today, many devices invoke suspend with
high reliability and high frequency.
They may not want to be forced to pay
the performance cost of sync() on every suspend.

So here we make the file system sync() optional.
De-select CONFIG_SUSPEND_FS_SYNC to delete the call.
Keep CONFIG_SUSPEND_FS_SYNC keept the call, and also
includes the new sysfs attribte,
/sys/power/suspend_fs_sync
which can be cleared to disable the file-system sync.

As we have had this call for a long time,
the default remains to keep the call, and to
invoke it on every suspend.

Signed-off-by: Len Brown <len....@intel.com>
---
kernel/power/Kconfig | 11 +++++++++++
kernel/power/main.c | 33 +++++++++++++++++++++++++++++++++
kernel/power/power.h | 1 +
kernel/power/suspend.c | 10 +++++++---
4 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 2fac9cc..244c2d9 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -102,6 +102,17 @@ config PM_SLEEP_SMP
depends on PM_SLEEP
select HOTPLUG_CPU

+config SUSPEND_FS_SYNC
+ bool "Suspend to RAM includes file-system sync()"
+ default y
+ depends on SUSPEND
+ ---help---
+ Include a file system sync() at the start of every suspend to RAM flow.
+ Disable this option to exclude that capability.
+
+ If included, the sync can still be skipped
+ by clearing /sys/power/suspend_fs_sync.
+
config PM_AUTOSLEEP
bool "Opportunistic sleep"
depends on PM_SLEEP
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 1d1bf63..bce7807 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -71,6 +71,36 @@ static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,

power_attr(pm_async);

+#ifdef CONFIG_SUSPEND_FS_SYNC
+
+/* If set, sync file systems at start of suspend flow */
+int suspend_fs_sync_enabled = 1;
+
+static ssize_t suspend_fs_sync_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", suspend_fs_sync_enabled);
+}
+
+static ssize_t suspend_fs_sync_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned long val;
+
+ if (kstrtoul(buf, 10, &val))
+ return -EINVAL;
+
+ if (val > 1)
+ return -EINVAL;
+
+ suspend_fs_sync_enabled = val;
+ return n;
+}
+
+power_attr(suspend_fs_sync);
+
+#endif /* CONFIG_SUSPEND_FS_SYNC */
+
#ifdef CONFIG_PM_DEBUG
int pm_test_level = TEST_NONE;

@@ -592,6 +622,9 @@ static struct attribute * g[] = {
#ifdef CONFIG_PM_SLEEP
&pm_async_attr.attr,
&wakeup_count_attr.attr,
+#ifdef CONFIG_SUSPEND_FS_SYNC
+ &suspend_fs_sync_attr.attr,
+#endif
#ifdef CONFIG_PM_AUTOSLEEP
&autosleep_attr.attr,
#endif
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 7d4b7ff..3d86f09 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -200,6 +200,7 @@ static inline void suspend_test_finish(const char *label) {}
#ifdef CONFIG_PM_SLEEP
/* kernel/power/main.c */
extern int pm_notifier_call_chain(unsigned long val);
+extern int suspend_fs_sync_enabled;
#endif

#ifdef CONFIG_HIGHMEM
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 62ee437..e7eb2ba 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -333,9 +333,13 @@ static int enter_state(suspend_state_t state)
if (state == PM_SUSPEND_FREEZE)
freeze_begin();

- printk(KERN_INFO "PM: Syncing filesystems ... ");
- sys_sync();
- printk("done.\n");
+#ifdef CONFIG_SUSPEND_FS_SYNC
+ if (suspend_fs_sync_enabled) {
+ printk(KERN_INFO "PM: Syncing filesystems ... ");
+ sys_sync();
+ printk("done.\n");
+ }
+#endif /* CONFIG_SUSPEND_FS_SYNC */

Srivatsa S. Bhat

unread,
Jan 23, 2014, 3:50:01 AM1/23/14
to
On 01/23/2014 01:40 PM, Len Brown wrote:
> From: Len Brown <len....@intel.com>
>
> Linux suspend-to-RAM was unreliable when first developed,
> and so sys_sync() was invoked inside the kernel at the
> start of every suspend flow.
>
> Today, many devices invoke suspend with
> high reliability and high frequency.
> They may not want to be forced to pay
> the performance cost of sync() on every suspend.
>
> So here we make the file system sync() optional.
> De-select CONFIG_SUSPEND_FS_SYNC to delete the call.
> Keep CONFIG_SUSPEND_FS_SYNC keept the call, and also
> includes the new sysfs attribte,
> /sys/power/suspend_fs_sync
> which can be cleared to disable the file-system sync.
>
> As we have had this call for a long time,
> the default remains to keep the call, and to
> invoke it on every suspend.
>
> Signed-off-by: Len Brown <len....@intel.com>

Reviewed-by: Srivatsa S. Bhat <srivat...@linux.vnet.ibm.com>

Regards,
Srivatsa S. Bhat

Pavel Machek

unread,
Jan 26, 2014, 4:10:02 PM1/26/14
to
Hi!

> From: Len Brown <len....@intel.com>
>
> Linux suspend-to-RAM was unreliable when first developed,
> and so sys_sync() was invoked inside the kernel at the
> start of every suspend flow.
>
> Today, many devices are invoking suspend with
> high reliability and high frequency, and they don't
> want to be forced to pay for sync on every suspend.
>
> So here we make it optional.
> De-select CONFIG_PM_SLEEP_SYNC to delete the call entirely.
> or keep CONFIG_PM_SLEEP and you can now clear the
> sys/power/sleep_sync attribte to disable the sync
> from user-space.

Dunno. Config option plus sysfs attribute is overdoing it a bit.
Maybe we could do

echo memfast > state

to enter suspend without sync? Patch should be simpler that way,
and we won't have to keep the state...

Pavel

Len Brown

unread,
May 8, 2015, 2:50:05 AM5/8/15
to
On Sun, Jan 26, 2014 at 4:08 PM, Pavel Machek <pa...@ucw.cz> wrote:

> Dunno. Config option plus sysfs attribute is overdoing it a bit.

Agreed.
Have discussed w/ Rafael, and current plan is to simply delete.
Updated patch on the way...

thanks,
Len Brown, Intel Open Source Technology Center
0 new messages