summaryrefslogtreecommitdiff
path: root/kernel/power/main.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2022-08-22 14:18:17 +0300
committerPeter Zijlstra <peterz@infradead.org>2022-09-07 22:53:48 +0300
commit5950e5d574c636a07dd21a872c2f8b41f6d20c55 (patch)
tree77419bad4e34bcffa13046fc8c673b67276ccd7b /kernel/power/main.c
parent0b9d46fc5ef7a457cc635b30b010081228cb81ac (diff)
downloadlinux-5950e5d574c636a07dd21a872c2f8b41f6d20c55.tar.xz
freezer: Have {,un}lock_system_sleep() save/restore flags
Rafael explained that the reason for having both PF_NOFREEZE and PF_FREEZER_SKIP is that {,un}lock_system_sleep() is callable from kthread context that has previously called set_freezable(). In preparation of merging the flags, have {,un}lock_system_slee() save and restore current->flags. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/20220822114648.725003428@infradead.org
Diffstat (limited to 'kernel/power/main.c')
-rw-r--r--kernel/power/main.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c
index e3694034b753..dae3d17919e6 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -21,14 +21,16 @@
#ifdef CONFIG_PM_SLEEP
-void lock_system_sleep(void)
+unsigned int lock_system_sleep(void)
{
+ unsigned int flags = current->flags;
current->flags |= PF_FREEZER_SKIP;
mutex_lock(&system_transition_mutex);
+ return flags;
}
EXPORT_SYMBOL_GPL(lock_system_sleep);
-void unlock_system_sleep(void)
+void unlock_system_sleep(unsigned int flags)
{
/*
* Don't use freezer_count() because we don't want the call to
@@ -46,7 +48,8 @@ void unlock_system_sleep(void)
* Which means, if we use try_to_freeze() here, it would make them
* enter the refrigerator, thus causing hibernation to lockup.
*/
- current->flags &= ~PF_FREEZER_SKIP;
+ if (!(flags & PF_FREEZER_SKIP))
+ current->flags &= ~PF_FREEZER_SKIP;
mutex_unlock(&system_transition_mutex);
}
EXPORT_SYMBOL_GPL(unlock_system_sleep);
@@ -263,16 +266,17 @@ static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
+ unsigned int sleep_flags;
const char * const *s;
+ int error = -EINVAL;
int level;
char *p;
int len;
- int error = -EINVAL;
p = memchr(buf, '\n', n);
len = p ? p - buf : n;
- lock_system_sleep();
+ sleep_flags = lock_system_sleep();
level = TEST_FIRST;
for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
@@ -282,7 +286,7 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
break;
}
- unlock_system_sleep();
+ unlock_system_sleep(sleep_flags);
return error ? error : n;
}