[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250703133427.3301899-1-chenridong@huaweicloud.com>
Date: Thu, 3 Jul 2025 13:34:27 +0000
From: Chen Ridong <chenridong@...weicloud.com>
To: peterz@...radead.org,
rafael@...nel.org,
pavel@...nel.org,
timvp@...gle.com,
tj@...nel.org,
mkoutny@...e.com
Cc: linux-pm@...r.kernel.org,
linux-kernel@...r.kernel.org,
lujialin4@...wei.com,
chenridong@...wei.com
Subject: [PATCH next] sched,freezer: prevent tasks from escaping being frozen
From: Chen Ridong <chenridong@...wei.com>
The commit cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if not
frozen") modified the cgroup_freezing() logic to also verify that the
FROZEN flag is not set, which affects the return value of the freezing()
function.
In __refrigerator(), the FROZEN flag is set before checking whether the
task should be frozen. This creates a race condition where:
1. The task's FROZEN flag is set.
2. The cgroup freezer state changes to FROZEN (Can be triggered by reading
freezer.state).
3. freezing() is called and returns false.
As a result, the task may escape being frozen when it should be.
To fix this, move the setting of the FROZEN flag to occur just before
schedule(). This ensures the flag is only set when we're certain the
task must be switched out.
Fixes: cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if not frozen")
Reported-by: Zhong Jiawei<zhongjiawei1@...wei.com>
Signed-off-by: Chen Ridong <chenridong@...wei.com>
---
kernel/freezer.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/kernel/freezer.c b/kernel/freezer.c
index 8d530d0949ff..89edd7550d27 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -71,12 +71,6 @@ bool __refrigerator(bool check_kthr_stop)
for (;;) {
bool freeze;
- raw_spin_lock_irq(¤t->pi_lock);
- WRITE_ONCE(current->__state, TASK_FROZEN);
- /* unstale saved_state so that __thaw_task() will wake us up */
- current->saved_state = TASK_RUNNING;
- raw_spin_unlock_irq(¤t->pi_lock);
-
spin_lock_irq(&freezer_lock);
freeze = freezing(current) && !(check_kthr_stop && kthread_should_stop());
spin_unlock_irq(&freezer_lock);
@@ -84,6 +78,12 @@ bool __refrigerator(bool check_kthr_stop)
if (!freeze)
break;
+ raw_spin_lock_irq(¤t->pi_lock);
+ WRITE_ONCE(current->__state, TASK_FROZEN);
+ /* unstale saved_state so that __thaw_task() will wake us up */
+ current->saved_state = TASK_RUNNING;
+ raw_spin_unlock_irq(¤t->pi_lock);
+
was_frozen = true;
schedule();
}
--
2.34.1
Powered by blists - more mailing lists