Merge tag 'pm-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "These rework the system-wide PM driver flags, make runtime switching of cpuidle governors easier, improve the user space hibernation interface code, add intel-speed-select interface documentation, add more debug messages to the ACPI code handling suspend to idle, update the cpufreq core and drivers, fix a minor issue in the cpuidle core and update two cpuidle drivers, improve the PM-runtime framework, update the Intel RAPL power capping driver, update devfreq core and drivers, and clean up the cpupower utility. Specifics: - Rework the system-wide PM driver flags to make them easier to understand and use and update their documentation (Rafael Wysocki, Alan Stern). - Allow cpuidle governors to be switched at run time regardless of the kernel configuration and update the related documentation accordingly (Hanjun Guo). - Improve the resume device handling in the user space hibernarion interface code (Domenico Andreoli). - Document the intel-speed-select sysfs interface (Srinivas Pandruvada). - Make the ACPI code handing suspend to idle print more debug messages to help diagnose issues with it (Rafael Wysocki). - Fix a helper routine in the cpufreq core and correct a typo in the struct cpufreq_driver kerneldoc comment (Rafael Wysocki, Wang Wenhu). - Update cpufreq drivers: - Make the intel_pstate driver start in the passive mode by default on systems without HWP (Rafael Wysocki). - Add i.MX7ULP support to the imx-cpufreq-dt driver and add i.MX7ULP to the cpufreq-dt-platdev blacklist (Peng Fan). - Convert the qoriq cpufreq driver to a platform one, make the platform code create a suitable device object for it and add platform dependencies to it (Mian Yousaf Kaukab, Geert Uytterhoeven). - Fix wrong compatible binding in the qcom driver (Ansuel Smith). - Build the omap driver by default for ARCH_OMAP2PLUS (Anders Roxell). - Add r8a7742 SoC support to the dt cpufreq driver (Lad Prabhakar). - Update cpuidle core and drivers: - Fix three reference count leaks in error code paths in the cpuidle core (Qiushi Wu). - Convert Qualcomm SPM to a generic cpuidle driver (Stephan Gerhold). - Fix up the execution order when entering a domain idle state in the PSCI driver (Ulf Hansson). - Fix a reference counting issue related to clock management and clean up two oddities in the PM-runtime framework (Rafael Wysocki, Andy Shevchenko). - Add ElkhartLake support to the Intel RAPL power capping driver and remove an unused local MSR definition from it (Jacob Pan, Sumeet Pawnikar). - Update devfreq core and drivers: - Replace strncpy() with strscpy() in the devfreq core and use lockdep asserts instead of manual checks for a locked mutex in it (Dmitry Osipenko, Krzysztof Kozlowski). - Add a generic imx bus scaling driver and make it register an interconnect device (Leonard Crestez, Gustavo A. R. Silva). - Make the cpufreq notifier in the tegra30 driver take boosting into account and delete an unuseful error message from that driver (Dmitry Osipenko, Markus Elfring). - Remove unneeded semicolon from the cpupower code (Zou Wei)" * tag 'pm-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (51 commits) cpuidle: Fix three reference count leaks PM: runtime: Replace pm_runtime_callbacks_present() PM / devfreq: Use lockdep asserts instead of manual checks for locked mutex PM / devfreq: imx-bus: Fix inconsistent IS_ERR and PTR_ERR PM / devfreq: Replace strncpy with strscpy PM / devfreq: imx: Register interconnect device PM / devfreq: Add generic imx bus scaling driver PM / devfreq: tegra30: Delete an error message in tegra_devfreq_probe() PM / devfreq: tegra30: Make CPUFreq notifier to take into account boosting PM: hibernate: Restrict writes to the resume device PM: runtime: clk: Fix clk_pm_runtime_get() error path cpuidle: Convert Qualcomm SPM driver to a generic CPUidle driver ACPI: EC: PM: s2idle: Extend GPE dispatching debug message ACPI: PM: s2idle: Print type of wakeup debug messages powercap: RAPL: remove unused local MSR define PM: runtime: Make clear what we do when conditions are wrong in rpm_suspend() Documentation: admin-guide: pm: Document intel-speed-select PM: hibernate: Split off snapshot dev option PM: hibernate: Incorporate concurrency handling Documentation: ABI: make current_governer_ro as a candidate for removal ...
This commit is contained in:
@@ -80,6 +80,18 @@ config HIBERNATION
|
||||
|
||||
For more information take a look at <file:Documentation/power/swsusp.rst>.
|
||||
|
||||
config HIBERNATION_SNAPSHOT_DEV
|
||||
bool "Userspace snapshot device"
|
||||
depends on HIBERNATION
|
||||
default y
|
||||
---help---
|
||||
Device used by the uswsusp tools.
|
||||
|
||||
Say N if no snapshotting from userspace is needed, this also
|
||||
reduces the attack surface of the kernel.
|
||||
|
||||
If in doubt, say Y.
|
||||
|
||||
config PM_STD_PARTITION
|
||||
string "Default resume partition"
|
||||
depends on HIBERNATION
|
||||
|
@@ -10,7 +10,8 @@ obj-$(CONFIG_VT_CONSOLE_SLEEP) += console.o
|
||||
obj-$(CONFIG_FREEZER) += process.o
|
||||
obj-$(CONFIG_SUSPEND) += suspend.o
|
||||
obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o
|
||||
obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o
|
||||
obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o
|
||||
obj-$(CONFIG_HIBERNATION_SNAPSHOT_DEV) += user.o
|
||||
obj-$(CONFIG_PM_AUTOSLEEP) += autosleep.o
|
||||
obj-$(CONFIG_PM_WAKELOCKS) += wakelock.o
|
||||
|
||||
|
@@ -67,6 +67,18 @@ bool freezer_test_done;
|
||||
|
||||
static const struct platform_hibernation_ops *hibernation_ops;
|
||||
|
||||
static atomic_t hibernate_atomic = ATOMIC_INIT(1);
|
||||
|
||||
bool hibernate_acquire(void)
|
||||
{
|
||||
return atomic_add_unless(&hibernate_atomic, -1, 0);
|
||||
}
|
||||
|
||||
void hibernate_release(void)
|
||||
{
|
||||
atomic_inc(&hibernate_atomic);
|
||||
}
|
||||
|
||||
bool hibernation_available(void)
|
||||
{
|
||||
return nohibernate == 0 && !security_locked_down(LOCKDOWN_HIBERNATION);
|
||||
@@ -704,7 +716,7 @@ int hibernate(void)
|
||||
|
||||
lock_system_sleep();
|
||||
/* The snapshot device should not be opened while we're running */
|
||||
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
|
||||
if (!hibernate_acquire()) {
|
||||
error = -EBUSY;
|
||||
goto Unlock;
|
||||
}
|
||||
@@ -775,7 +787,7 @@ int hibernate(void)
|
||||
Exit:
|
||||
__pm_notifier_call_chain(PM_POST_HIBERNATION, nr_calls, NULL);
|
||||
pm_restore_console();
|
||||
atomic_inc(&snapshot_device_available);
|
||||
hibernate_release();
|
||||
Unlock:
|
||||
unlock_system_sleep();
|
||||
pr_info("hibernation exit\n");
|
||||
@@ -880,7 +892,7 @@ static int software_resume(void)
|
||||
goto Unlock;
|
||||
|
||||
/* The snapshot device should not be opened while we're running */
|
||||
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
|
||||
if (!hibernate_acquire()) {
|
||||
error = -EBUSY;
|
||||
swsusp_close(FMODE_READ);
|
||||
goto Unlock;
|
||||
@@ -911,7 +923,7 @@ static int software_resume(void)
|
||||
__pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
|
||||
pm_restore_console();
|
||||
pr_info("resume failed (%d)\n", error);
|
||||
atomic_inc(&snapshot_device_available);
|
||||
hibernate_release();
|
||||
/* For success case, the suspend path will release the lock */
|
||||
Unlock:
|
||||
mutex_unlock(&system_transition_mutex);
|
||||
|
@@ -154,8 +154,8 @@ extern int snapshot_write_next(struct snapshot_handle *handle);
|
||||
extern void snapshot_write_finalize(struct snapshot_handle *handle);
|
||||
extern int snapshot_image_loaded(struct snapshot_handle *handle);
|
||||
|
||||
/* If unset, the snapshot device cannot be open. */
|
||||
extern atomic_t snapshot_device_available;
|
||||
extern bool hibernate_acquire(void);
|
||||
extern void hibernate_release(void);
|
||||
|
||||
extern sector_t alloc_swapdev_block(int swap);
|
||||
extern void free_all_swap_pages(int swap);
|
||||
|
@@ -35,9 +35,13 @@ static struct snapshot_data {
|
||||
bool ready;
|
||||
bool platform_support;
|
||||
bool free_bitmaps;
|
||||
struct inode *bd_inode;
|
||||
} snapshot_state;
|
||||
|
||||
atomic_t snapshot_device_available = ATOMIC_INIT(1);
|
||||
int is_hibernate_resume_dev(const struct inode *bd_inode)
|
||||
{
|
||||
return hibernation_available() && snapshot_state.bd_inode == bd_inode;
|
||||
}
|
||||
|
||||
static int snapshot_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
@@ -49,13 +53,13 @@ static int snapshot_open(struct inode *inode, struct file *filp)
|
||||
|
||||
lock_system_sleep();
|
||||
|
||||
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
|
||||
if (!hibernate_acquire()) {
|
||||
error = -EBUSY;
|
||||
goto Unlock;
|
||||
}
|
||||
|
||||
if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
|
||||
atomic_inc(&snapshot_device_available);
|
||||
hibernate_release();
|
||||
error = -ENOSYS;
|
||||
goto Unlock;
|
||||
}
|
||||
@@ -92,11 +96,12 @@ static int snapshot_open(struct inode *inode, struct file *filp)
|
||||
__pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
|
||||
}
|
||||
if (error)
|
||||
atomic_inc(&snapshot_device_available);
|
||||
hibernate_release();
|
||||
|
||||
data->frozen = false;
|
||||
data->ready = false;
|
||||
data->platform_support = false;
|
||||
data->bd_inode = NULL;
|
||||
|
||||
Unlock:
|
||||
unlock_system_sleep();
|
||||
@@ -112,6 +117,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
|
||||
|
||||
swsusp_free();
|
||||
data = filp->private_data;
|
||||
data->bd_inode = NULL;
|
||||
free_all_swap_pages(data->swap);
|
||||
if (data->frozen) {
|
||||
pm_restore_gfp_mask();
|
||||
@@ -122,7 +128,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
|
||||
}
|
||||
pm_notifier_call_chain(data->mode == O_RDONLY ?
|
||||
PM_POST_HIBERNATION : PM_POST_RESTORE);
|
||||
atomic_inc(&snapshot_device_available);
|
||||
hibernate_release();
|
||||
|
||||
unlock_system_sleep();
|
||||
|
||||
@@ -204,6 +210,7 @@ struct compat_resume_swap_area {
|
||||
static int snapshot_set_swap_area(struct snapshot_data *data,
|
||||
void __user *argp)
|
||||
{
|
||||
struct block_device *bdev;
|
||||
sector_t offset;
|
||||
dev_t swdev;
|
||||
|
||||
@@ -234,9 +241,12 @@ static int snapshot_set_swap_area(struct snapshot_data *data,
|
||||
data->swap = -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
data->swap = swap_type_of(swdev, offset, NULL);
|
||||
data->swap = swap_type_of(swdev, offset, &bdev);
|
||||
if (data->swap < 0)
|
||||
return -ENODEV;
|
||||
|
||||
data->bd_inode = bdev->bd_inode;
|
||||
bdput(bdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user