Freezer retry loops during suspend are often triggered by tasks entering
D-state (TASK_UNINTERRUPTIBLE), which cannot be frozen. This patch adds
a simple retry counter to freeze_processes() to help quantify how many
attempts were required before all tasks entered the frozen state. This
is useful for performance tuning and debugging unpredictable suspend
delays.
A new dmesg log is added for visibility:
freeze round: xx, tasks to freeze: xx
This message allows users to correlate freeze instability with system
state.
Signed-off-by: Zihuan Zhang <zhangzihuan@kylinos.cn>
---
kernel/power/process.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/power/process.c b/kernel/power/process.c
index dc0dfc349f22..87616ca710ac 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -32,6 +32,7 @@ static int try_to_freeze_tasks(bool user_only)
struct task_struct *g, *p;
unsigned long end_time;
unsigned int todo;
+ unsigned int retry = 0;
bool wq_busy = false;
ktime_t start, end, elapsed;
unsigned int elapsed_msecs;
@@ -63,6 +64,8 @@ static int try_to_freeze_tasks(bool user_only)
todo += wq_busy;
}
+ pm_pr_dbg("freeze round: %d, task to freeze: %d\n", retry, todo);
+
if (!todo || time_after(jiffies, end_time))
break;
@@ -79,6 +82,7 @@ static int try_to_freeze_tasks(bool user_only)
usleep_range(sleep_usecs / 2, sleep_usecs);
if (sleep_usecs < 8 * USEC_PER_MSEC)
sleep_usecs *= 2;
+ retry++;
}
end = ktime_get_boottime();
--
2.25.1
On Thu, Jun 19, 2025 at 5:54 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote: > > Freezer retry loops during suspend are often triggered by tasks entering > D-state (TASK_UNINTERRUPTIBLE), which cannot be frozen. This patch adds > a simple retry counter to freeze_processes() to help quantify how many > attempts were required before all tasks entered the frozen state. This > is useful for performance tuning and debugging unpredictable suspend > delays. > > A new dmesg log is added for visibility: > > freeze round: xx, tasks to freeze: xx > > This message allows users to correlate freeze instability with system > state. > > Signed-off-by: Zihuan Zhang <zhangzihuan@kylinos.cn> > --- > kernel/power/process.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/kernel/power/process.c b/kernel/power/process.c > index dc0dfc349f22..87616ca710ac 100644 > --- a/kernel/power/process.c > +++ b/kernel/power/process.c > @@ -32,6 +32,7 @@ static int try_to_freeze_tasks(bool user_only) > struct task_struct *g, *p; > unsigned long end_time; > unsigned int todo; > + unsigned int retry = 0; > bool wq_busy = false; > ktime_t start, end, elapsed; > unsigned int elapsed_msecs; > @@ -63,6 +64,8 @@ static int try_to_freeze_tasks(bool user_only) > todo += wq_busy; > } > > + pm_pr_dbg("freeze round: %d, task to freeze: %d\n", retry, todo); > + This is kind of fine if it is really needed, but it needs to have a separate on/off switch as far as I'm concerned. Maybe use pr_debug() for it in which case it would be controlled via dynamic debug? > if (!todo || time_after(jiffies, end_time)) > break; > > @@ -79,6 +82,7 @@ static int try_to_freeze_tasks(bool user_only) > usleep_range(sleep_usecs / 2, sleep_usecs); > if (sleep_usecs < 8 * USEC_PER_MSEC) > sleep_usecs *= 2; > + retry++; > } > > end = ktime_get_boottime(); > -- > 2.25.1 >
Hi Rafael, Thanks for the feedback. 在 2025/7/3 22:38, Rafael J. Wysocki 写道: > On Thu, Jun 19, 2025 at 5:54 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote: >> Freezer retry loops during suspend are often triggered by tasks entering >> D-state (TASK_UNINTERRUPTIBLE), which cannot be frozen. This patch adds >> a simple retry counter to freeze_processes() to help quantify how many >> attempts were required before all tasks entered the frozen state. This >> is useful for performance tuning and debugging unpredictable suspend >> delays. >> >> A new dmesg log is added for visibility: >> >> freeze round: xx, tasks to freeze: xx >> >> This message allows users to correlate freeze instability with system >> state. >> >> Signed-off-by: Zihuan Zhang <zhangzihuan@kylinos.cn> >> --- >> kernel/power/process.c | 4 ++++ >> 1 file changed, 4 insertions(+) >> >> diff --git a/kernel/power/process.c b/kernel/power/process.c >> index dc0dfc349f22..87616ca710ac 100644 >> --- a/kernel/power/process.c >> +++ b/kernel/power/process.c >> @@ -32,6 +32,7 @@ static int try_to_freeze_tasks(bool user_only) >> struct task_struct *g, *p; >> unsigned long end_time; >> unsigned int todo; >> + unsigned int retry = 0; >> bool wq_busy = false; >> ktime_t start, end, elapsed; >> unsigned int elapsed_msecs; >> @@ -63,6 +64,8 @@ static int try_to_freeze_tasks(bool user_only) >> todo += wq_busy; >> } >> >> + pm_pr_dbg("freeze round: %d, task to freeze: %d\n", retry, todo); >> + > This is kind of fine if it is really needed, but it needs to have a > separate on/off switch as far as I'm concerned. > > Maybe use pr_debug() for it in which case it would be controlled via > dynamic debug? I agree with your suggestion — I’ll switch to pr_debug() in the next version so that the message can be controlled via dynamic debug. >> if (!todo || time_after(jiffies, end_time)) >> break; >> >> @@ -79,6 +82,7 @@ static int try_to_freeze_tasks(bool user_only) >> usleep_range(sleep_usecs / 2, sleep_usecs); >> if (sleep_usecs < 8 * USEC_PER_MSEC) >> sleep_usecs *= 2; >> + retry++; >> } >> >> end = ktime_get_boottime(); >> -- >> 2.25.1 >> Best regards, Zihuan Zhang
© 2016 - 2025 Red Hat, Inc.