Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
322e929d
Commit
322e929d
authored
Jan 23, 2020
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back new material related to system-wide PM for v5.6.
parents
18451f9f
c052bf82
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
87 additions
and
28 deletions
+87
-28
Documentation/ABI/testing/sysfs-power
Documentation/ABI/testing/sysfs-power
+13
-0
drivers/base/power/wakeup.c
drivers/base/power/wakeup.c
+3
-0
include/linux/suspend.h
include/linux/suspend.h
+2
-0
kernel/power/Kconfig
kernel/power/Kconfig
+4
-1
kernel/power/hibernate.c
kernel/power/hibernate.c
+12
-11
kernel/power/main.c
kernel/power/main.c
+33
-0
kernel/power/snapshot.c
kernel/power/snapshot.c
+16
-12
kernel/power/suspend.c
kernel/power/suspend.c
+1
-1
kernel/power/suspend_test.c
kernel/power/suspend_test.c
+3
-3
No files found.
Documentation/ABI/testing/sysfs-power
View file @
322e929d
...
@@ -407,3 +407,16 @@ Contact: Kalesh Singh <kaleshsingh96@gmail.com>
...
@@ -407,3 +407,16 @@ Contact: Kalesh Singh <kaleshsingh96@gmail.com>
Description:
Description:
The /sys/power/suspend_stats/last_failed_step file contains
The /sys/power/suspend_stats/last_failed_step file contains
the last failed step in the suspend/resume path.
the last failed step in the suspend/resume path.
What: /sys/power/sync_on_suspend
Date: October 2019
Contact: Jonas Meurer <jonas@freesources.org>
Description:
This file controls whether or not the kernel will sync()
filesystems during system suspend (after freezing user space
and before suspending devices).
Writing a "1" to this file enables the sync() and writing a "0"
disables it. Reads from the file return the current value.
The default is "1" if the build-time "SUSPEND_SKIP_SYNC" config
flag is unset, or "0" otherwise.
drivers/base/power/wakeup.c
View file @
322e929d
...
@@ -1125,6 +1125,9 @@ static void *wakeup_sources_stats_seq_next(struct seq_file *m,
...
@@ -1125,6 +1125,9 @@ static void *wakeup_sources_stats_seq_next(struct seq_file *m,
break
;
break
;
}
}
if
(
!
next_ws
)
print_wakeup_source_stats
(
m
,
&
deleted_ws
);
return
next_ws
;
return
next_ws
;
}
}
...
...
include/linux/suspend.h
View file @
322e929d
...
@@ -329,6 +329,7 @@ extern void arch_suspend_disable_irqs(void);
...
@@ -329,6 +329,7 @@ extern void arch_suspend_disable_irqs(void);
extern
void
arch_suspend_enable_irqs
(
void
);
extern
void
arch_suspend_enable_irqs
(
void
);
extern
int
pm_suspend
(
suspend_state_t
state
);
extern
int
pm_suspend
(
suspend_state_t
state
);
extern
bool
sync_on_suspend_enabled
;
#else
/* !CONFIG_SUSPEND */
#else
/* !CONFIG_SUSPEND */
#define suspend_valid_only_mem NULL
#define suspend_valid_only_mem NULL
...
@@ -342,6 +343,7 @@ static inline bool pm_suspend_default_s2idle(void) { return false; }
...
@@ -342,6 +343,7 @@ static inline bool pm_suspend_default_s2idle(void) { return false; }
static
inline
void
suspend_set_ops
(
const
struct
platform_suspend_ops
*
ops
)
{}
static
inline
void
suspend_set_ops
(
const
struct
platform_suspend_ops
*
ops
)
{}
static
inline
int
pm_suspend
(
suspend_state_t
state
)
{
return
-
ENOSYS
;
}
static
inline
int
pm_suspend
(
suspend_state_t
state
)
{
return
-
ENOSYS
;
}
static
inline
bool
sync_on_suspend_enabled
(
void
)
{
return
true
;
}
static
inline
bool
idle_should_enter_s2idle
(
void
)
{
return
false
;
}
static
inline
bool
idle_should_enter_s2idle
(
void
)
{
return
false
;
}
static
inline
void
__init
pm_states_init
(
void
)
{}
static
inline
void
__init
pm_states_init
(
void
)
{}
static
inline
void
s2idle_set_ops
(
const
struct
platform_s2idle_ops
*
ops
)
{}
static
inline
void
s2idle_set_ops
(
const
struct
platform_s2idle_ops
*
ops
)
{}
...
...
kernel/power/Kconfig
View file @
322e929d
...
@@ -27,7 +27,10 @@ config SUSPEND_SKIP_SYNC
...
@@ -27,7 +27,10 @@ config SUSPEND_SKIP_SYNC
Skip the kernel sys_sync() before freezing user processes.
Skip the kernel sys_sync() before freezing user processes.
Some systems prefer not to pay this cost on every invocation
Some systems prefer not to pay this cost on every invocation
of suspend, or they are content with invoking sync() from
of suspend, or they are content with invoking sync() from
user-space before invoking suspend. Say Y if that's your case.
user-space before invoking suspend. There's a run-time switch
at '/sys/power/sync_on_suspend' to configure this behaviour.
This setting changes the default for the run-tim switch. Say Y
to change the default to disable the kernel sys_sync().
config HIBERNATE_CALLBACKS
config HIBERNATE_CALLBACKS
bool
bool
...
...
kernel/power/hibernate.c
View file @
322e929d
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Copyright (C) 2012 Bojan Smojver <bojan@rexursive.com>
* Copyright (C) 2012 Bojan Smojver <bojan@rexursive.com>
*/
*/
#define pr_fmt(fmt) "PM: " fmt
#define pr_fmt(fmt) "PM:
hibernation:
" fmt
#include <linux/export.h>
#include <linux/export.h>
#include <linux/suspend.h>
#include <linux/suspend.h>
...
@@ -106,7 +106,7 @@ EXPORT_SYMBOL(system_entering_hibernation);
...
@@ -106,7 +106,7 @@ EXPORT_SYMBOL(system_entering_hibernation);
#ifdef CONFIG_PM_DEBUG
#ifdef CONFIG_PM_DEBUG
static
void
hibernation_debug_sleep
(
void
)
static
void
hibernation_debug_sleep
(
void
)
{
{
pr_info
(
"
hibernation
debug: Waiting for 5 seconds.
\n
"
);
pr_info
(
"debug: Waiting for 5 seconds.
\n
"
);
mdelay
(
5000
);
mdelay
(
5000
);
}
}
...
@@ -277,7 +277,7 @@ static int create_image(int platform_mode)
...
@@ -277,7 +277,7 @@ static int create_image(int platform_mode)
error
=
dpm_suspend_end
(
PMSG_FREEZE
);
error
=
dpm_suspend_end
(
PMSG_FREEZE
);
if
(
error
)
{
if
(
error
)
{
pr_err
(
"Some devices failed to power down, aborting
hibernation
\n
"
);
pr_err
(
"Some devices failed to power down, aborting
\n
"
);
return
error
;
return
error
;
}
}
...
@@ -295,7 +295,7 @@ static int create_image(int platform_mode)
...
@@ -295,7 +295,7 @@ static int create_image(int platform_mode)
error
=
syscore_suspend
();
error
=
syscore_suspend
();
if
(
error
)
{
if
(
error
)
{
pr_err
(
"Some system devices failed to power down, aborting
hibernation
\n
"
);
pr_err
(
"Some system devices failed to power down, aborting
\n
"
);
goto
Enable_irqs
;
goto
Enable_irqs
;
}
}
...
@@ -310,7 +310,7 @@ static int create_image(int platform_mode)
...
@@ -310,7 +310,7 @@ static int create_image(int platform_mode)
restore_processor_state
();
restore_processor_state
();
trace_suspend_resume
(
TPS
(
"machine_suspend"
),
PM_EVENT_HIBERNATE
,
false
);
trace_suspend_resume
(
TPS
(
"machine_suspend"
),
PM_EVENT_HIBERNATE
,
false
);
if
(
error
)
if
(
error
)
pr_err
(
"Error %d creating
hibernation
image
\n
"
,
error
);
pr_err
(
"Error %d creating image
\n
"
,
error
);
if
(
!
in_suspend
)
{
if
(
!
in_suspend
)
{
events_check_enabled
=
false
;
events_check_enabled
=
false
;
...
@@ -680,7 +680,7 @@ static int load_image_and_restore(void)
...
@@ -680,7 +680,7 @@ static int load_image_and_restore(void)
if
(
!
error
)
if
(
!
error
)
hibernation_restore
(
flags
&
SF_PLATFORM_MODE
);
hibernation_restore
(
flags
&
SF_PLATFORM_MODE
);
pr_err
(
"Failed to load
hibernation
image, recovering.
\n
"
);
pr_err
(
"Failed to load image, recovering.
\n
"
);
swsusp_free
();
swsusp_free
();
free_basic_memory_bitmaps
();
free_basic_memory_bitmaps
();
Unlock:
Unlock:
...
@@ -743,7 +743,7 @@ int hibernate(void)
...
@@ -743,7 +743,7 @@ int hibernate(void)
else
else
flags
|=
SF_CRC32_MODE
;
flags
|=
SF_CRC32_MODE
;
pm_pr_dbg
(
"Writing image.
\n
"
);
pm_pr_dbg
(
"Writing
hibernation
image.
\n
"
);
error
=
swsusp_write
(
flags
);
error
=
swsusp_write
(
flags
);
swsusp_free
();
swsusp_free
();
if
(
!
error
)
{
if
(
!
error
)
{
...
@@ -755,7 +755,7 @@ int hibernate(void)
...
@@ -755,7 +755,7 @@ int hibernate(void)
in_suspend
=
0
;
in_suspend
=
0
;
pm_restore_gfp_mask
();
pm_restore_gfp_mask
();
}
else
{
}
else
{
pm_pr_dbg
(
"
I
mage restored successfully.
\n
"
);
pm_pr_dbg
(
"
Hibernation i
mage restored successfully.
\n
"
);
}
}
Free_bitmaps:
Free_bitmaps:
...
@@ -894,7 +894,7 @@ static int software_resume(void)
...
@@ -894,7 +894,7 @@ static int software_resume(void)
goto
Close_Finish
;
goto
Close_Finish
;
}
}
pm_pr_dbg
(
"Preparing processes for restore.
\n
"
);
pm_pr_dbg
(
"Preparing processes for
hibernation
restore.
\n
"
);
error
=
freeze_processes
();
error
=
freeze_processes
();
if
(
error
)
if
(
error
)
goto
Close_Finish
;
goto
Close_Finish
;
...
@@ -903,7 +903,7 @@ static int software_resume(void)
...
@@ -903,7 +903,7 @@ static int software_resume(void)
Finish:
Finish:
__pm_notifier_call_chain
(
PM_POST_RESTORE
,
nr_calls
,
NULL
);
__pm_notifier_call_chain
(
PM_POST_RESTORE
,
nr_calls
,
NULL
);
pm_restore_console
();
pm_restore_console
();
pr_info
(
"resume f
rom hibernation f
ailed (%d)
\n
"
,
error
);
pr_info
(
"resume failed (%d)
\n
"
,
error
);
atomic_inc
(
&
snapshot_device_available
);
atomic_inc
(
&
snapshot_device_available
);
/* For success case, the suspend path will release the lock */
/* For success case, the suspend path will release the lock */
Unlock:
Unlock:
...
@@ -1068,7 +1068,8 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
...
@@ -1068,7 +1068,8 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
lock_system_sleep
();
lock_system_sleep
();
swsusp_resume_device
=
res
;
swsusp_resume_device
=
res
;
unlock_system_sleep
();
unlock_system_sleep
();
pm_pr_dbg
(
"Configured resume from disk to %u
\n
"
,
swsusp_resume_device
);
pm_pr_dbg
(
"Configured hibernation resume from disk to %u
\n
"
,
swsusp_resume_device
);
noresume
=
0
;
noresume
=
0
;
software_resume
();
software_resume
();
return
n
;
return
n
;
...
...
kernel/power/main.c
View file @
322e929d
...
@@ -190,6 +190,38 @@ static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr
...
@@ -190,6 +190,38 @@ static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr
}
}
power_attr
(
mem_sleep
);
power_attr
(
mem_sleep
);
/*
* sync_on_suspend: invoke ksys_sync_helper() before suspend.
*
* show() returns whether ksys_sync_helper() is invoked before suspend.
* store() accepts 0 or 1. 0 disables ksys_sync_helper() and 1 enables it.
*/
bool
sync_on_suspend_enabled
=
!
IS_ENABLED
(
CONFIG_SUSPEND_SKIP_SYNC
);
static
ssize_t
sync_on_suspend_show
(
struct
kobject
*
kobj
,
struct
kobj_attribute
*
attr
,
char
*
buf
)
{
return
sprintf
(
buf
,
"%d
\n
"
,
sync_on_suspend_enabled
);
}
static
ssize_t
sync_on_suspend_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
;
sync_on_suspend_enabled
=
!!
val
;
return
n
;
}
power_attr
(
sync_on_suspend
);
#endif
/* CONFIG_SUSPEND */
#endif
/* CONFIG_SUSPEND */
#ifdef CONFIG_PM_SLEEP_DEBUG
#ifdef CONFIG_PM_SLEEP_DEBUG
...
@@ -855,6 +887,7 @@ static struct attribute * g[] = {
...
@@ -855,6 +887,7 @@ static struct attribute * g[] = {
&
wakeup_count_attr
.
attr
,
&
wakeup_count_attr
.
attr
,
#ifdef CONFIG_SUSPEND
#ifdef CONFIG_SUSPEND
&
mem_sleep_attr
.
attr
,
&
mem_sleep_attr
.
attr
,
&
sync_on_suspend_attr
.
attr
,
#endif
#endif
#ifdef CONFIG_PM_AUTOSLEEP
#ifdef CONFIG_PM_AUTOSLEEP
&
autosleep_attr
.
attr
,
&
autosleep_attr
.
attr
,
...
...
kernel/power/snapshot.c
View file @
322e929d
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
* Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
* Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
*/
*/
#define pr_fmt(fmt) "PM: " fmt
#define pr_fmt(fmt) "PM:
hibernation:
" fmt
#include <linux/version.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/module.h>
...
@@ -1566,9 +1566,7 @@ static unsigned long preallocate_image_highmem(unsigned long nr_pages)
...
@@ -1566,9 +1566,7 @@ static unsigned long preallocate_image_highmem(unsigned long nr_pages)
*/
*/
static
unsigned
long
__fraction
(
u64
x
,
u64
multiplier
,
u64
base
)
static
unsigned
long
__fraction
(
u64
x
,
u64
multiplier
,
u64
base
)
{
{
x
*=
multiplier
;
return
div64_u64
(
x
*
multiplier
,
base
);
do_div
(
x
,
base
);
return
(
unsigned
long
)
x
;
}
}
static
unsigned
long
preallocate_highmem_fraction
(
unsigned
long
nr_pages
,
static
unsigned
long
preallocate_highmem_fraction
(
unsigned
long
nr_pages
,
...
@@ -1705,16 +1703,20 @@ int hibernate_preallocate_memory(void)
...
@@ -1705,16 +1703,20 @@ int hibernate_preallocate_memory(void)
ktime_t
start
,
stop
;
ktime_t
start
,
stop
;
int
error
;
int
error
;
pr_info
(
"Preallocating image memory
...
"
);
pr_info
(
"Preallocating image memory
\n
"
);
start
=
ktime_get
();
start
=
ktime_get
();
error
=
memory_bm_create
(
&
orig_bm
,
GFP_IMAGE
,
PG_ANY
);
error
=
memory_bm_create
(
&
orig_bm
,
GFP_IMAGE
,
PG_ANY
);
if
(
error
)
if
(
error
)
{
pr_err
(
"Cannot allocate original bitmap
\n
"
);
goto
err_out
;
goto
err_out
;
}
error
=
memory_bm_create
(
&
copy_bm
,
GFP_IMAGE
,
PG_ANY
);
error
=
memory_bm_create
(
&
copy_bm
,
GFP_IMAGE
,
PG_ANY
);
if
(
error
)
if
(
error
)
{
pr_err
(
"Cannot allocate copy bitmap
\n
"
);
goto
err_out
;
goto
err_out
;
}
alloc_normal
=
0
;
alloc_normal
=
0
;
alloc_highmem
=
0
;
alloc_highmem
=
0
;
...
@@ -1804,8 +1806,11 @@ int hibernate_preallocate_memory(void)
...
@@ -1804,8 +1806,11 @@ int hibernate_preallocate_memory(void)
alloc
-=
pages
;
alloc
-=
pages
;
pages
+=
pages_highmem
;
pages
+=
pages_highmem
;
pages_highmem
=
preallocate_image_highmem
(
alloc
);
pages_highmem
=
preallocate_image_highmem
(
alloc
);
if
(
pages_highmem
<
alloc
)
if
(
pages_highmem
<
alloc
)
{
pr_err
(
"Image allocation is %lu pages short
\n
"
,
alloc
-
pages_highmem
);
goto
err_out
;
goto
err_out
;
}
pages
+=
pages_highmem
;
pages
+=
pages_highmem
;
/*
/*
* size is the desired number of saveable pages to leave in
* size is the desired number of saveable pages to leave in
...
@@ -1836,13 +1841,12 @@ int hibernate_preallocate_memory(void)
...
@@ -1836,13 +1841,12 @@ int hibernate_preallocate_memory(void)
out:
out:
stop
=
ktime_get
();
stop
=
ktime_get
();
pr_
cont
(
"done (allocated %lu pages)
\n
"
,
pages
);
pr_
info
(
"Allocated %lu pages for snapshot
\n
"
,
pages
);
swsusp_show_speed
(
start
,
stop
,
pages
,
"Allocated"
);
swsusp_show_speed
(
start
,
stop
,
pages
,
"Allocated"
);
return
0
;
return
0
;
err_out:
err_out:
pr_cont
(
"
\n
"
);
swsusp_free
();
swsusp_free
();
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
...
@@ -1976,7 +1980,7 @@ asmlinkage __visible int swsusp_save(void)
...
@@ -1976,7 +1980,7 @@ asmlinkage __visible int swsusp_save(void)
{
{
unsigned
int
nr_pages
,
nr_highmem
;
unsigned
int
nr_pages
,
nr_highmem
;
pr_info
(
"Creating
hibernation
image:
\n
"
);
pr_info
(
"Creating image:
\n
"
);
drain_local_pages
(
NULL
);
drain_local_pages
(
NULL
);
nr_pages
=
count_data_pages
();
nr_pages
=
count_data_pages
();
...
@@ -2010,7 +2014,7 @@ asmlinkage __visible int swsusp_save(void)
...
@@ -2010,7 +2014,7 @@ asmlinkage __visible int swsusp_save(void)
nr_copy_pages
=
nr_pages
;
nr_copy_pages
=
nr_pages
;
nr_meta_pages
=
DIV_ROUND_UP
(
nr_pages
*
sizeof
(
long
),
PAGE_SIZE
);
nr_meta_pages
=
DIV_ROUND_UP
(
nr_pages
*
sizeof
(
long
),
PAGE_SIZE
);
pr_info
(
"
Hibernation i
mage created (%d pages copied)
\n
"
,
nr_pages
);
pr_info
(
"
I
mage created (%d pages copied)
\n
"
,
nr_pages
);
return
0
;
return
0
;
}
}
...
...
kernel/power/suspend.c
View file @
322e929d
...
@@ -564,7 +564,7 @@ static int enter_state(suspend_state_t state)
...
@@ -564,7 +564,7 @@ static int enter_state(suspend_state_t state)
if
(
state
==
PM_SUSPEND_TO_IDLE
)
if
(
state
==
PM_SUSPEND_TO_IDLE
)
s2idle_begin
();
s2idle_begin
();
if
(
!
IS_ENABLED
(
CONFIG_SUSPEND_SKIP_SYNC
)
)
{
if
(
sync_on_suspend_enabled
)
{
trace_suspend_resume
(
TPS
(
"sync_filesystems"
),
0
,
true
);
trace_suspend_resume
(
TPS
(
"sync_filesystems"
),
0
,
true
);
ksys_sync_helper
();
ksys_sync_helper
();
trace_suspend_resume
(
TPS
(
"sync_filesystems"
),
0
,
false
);
trace_suspend_resume
(
TPS
(
"sync_filesystems"
),
0
,
false
);
...
...
kernel/power/suspend_test.c
View file @
322e929d
...
@@ -70,7 +70,7 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
...
@@ -70,7 +70,7 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
static
char
info_test
[]
__initdata
=
static
char
info_test
[]
__initdata
=
KERN_INFO
"PM: test RTC wakeup from '%s' suspend
\n
"
;
KERN_INFO
"PM: test RTC wakeup from '%s' suspend
\n
"
;
unsigned
long
now
;
time64_t
now
;
struct
rtc_wkalrm
alm
;
struct
rtc_wkalrm
alm
;
int
status
;
int
status
;
...
@@ -81,10 +81,10 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
...
@@ -81,10 +81,10 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
printk
(
err_readtime
,
dev_name
(
&
rtc
->
dev
),
status
);
printk
(
err_readtime
,
dev_name
(
&
rtc
->
dev
),
status
);
return
;
return
;
}
}
rtc_tm_to_time
(
&
alm
.
time
,
&
now
);
now
=
rtc_tm_to_time64
(
&
alm
.
time
);
memset
(
&
alm
,
0
,
sizeof
alm
);
memset
(
&
alm
,
0
,
sizeof
alm
);
rtc_time_to_tm
(
now
+
TEST_SUSPEND_SECONDS
,
&
alm
.
time
);
rtc_time
64
_to_tm
(
now
+
TEST_SUSPEND_SECONDS
,
&
alm
.
time
);
alm
.
enabled
=
true
;
alm
.
enabled
=
true
;
status
=
rtc_set_alarm
(
rtc
,
&
alm
);
status
=
rtc_set_alarm
(
rtc
,
&
alm
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment