[PATCH RFC] arm64: suspend: Fix context tracking during system suspend
"syzbot" <[email protected]> Wed, 29 Jul 2026 18:27:27 +0000 (UTC)
| Newsgroups | dev.linux.lists.syzbot |
|---|---|
| Message-ID | <[email protected]> |
Commit 19235e472798 ("cpuidle, arm64: Fix the ARM64 cpuidle logic") added
unconditional calls to ct_cpuidle_enter() and ct_cpuidle_exit() in
cpu_suspend() to keep RCU active longer before entering CPUIDLE. However,
cpu_suspend() is a dual-purpose function used both for CPUIDLE (called from
the idle task) and for system suspend (called synchronously by the task
initiating the suspend).
When cpu_suspend() is invoked during system suspend by a non-idle task,
ct_cpuidle_enter() triggers a warning in ct_kernel_exit() because it
expects to be called only from the idle task:
WARNING: kernel/context_tracking.c:120 at ct_kernel_exit+0x1b4/0x1f4
Call trace:
ct_kernel_exit+0x1b4/0x1f4
ct_idle_enter+0x24/0x38
ct_cpuidle_enter include/linux/cpuidle.h:134 [inline]
cpu_suspend+0x264/0x474
psci_system_suspend_enter+0x4c/0x80
suspend_enter kernel/power/suspend.c:468 [inline]
suspend_devices_and_enter+0x88c/0xd0c
Furthermore, ct_cpuidle_enter() incorrectly tells lockdep that interrupts
are enabled, which is true for CPUIDLE but wrong for system suspend where
interrupts are strictly disabled.
Fix this by conditionally calling ct_cpuidle_enter() and ct_cpuidle_exit()
only if the current task is the idle task. This preserves the required RCU
context tracking behavior for CPUIDLE without violating context tracking
assumptions during system suspend.
Fixes: 19235e472798 ("cpuidle, arm64: Fix the ARM64 cpuidle logic")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=79883955da3a62652a80
Link: https://syzkaller.appspot.com/ai_job?id=a12b1304-974c-4342-8eb2-8cae11276afb
To: "Catalin Marinas" <[email protected]>
To: <[email protected]>
To: "Will Deacon" <[email protected]>
To: "Peter Zijlstra" <[email protected]>
Cc: <[email protected]>
---
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index eaaff9432..c6b6b1cac 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -5,6 +5,7 @@
#include <linux/uaccess.h>
#include <linux/pgtable.h>
#include <linux/cpuidle.h>
+#include <linux/sched.h>
#include <asm/alternative.h>
#include <asm/cacheflush.h>
#include <asm/cpufeature.h>
@@ -99,6 +100,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
int ret = 0;
unsigned long flags;
struct sleep_stack_data state;
+ bool idle = is_idle_task(current);
struct arm_cpuidle_irq_context context;
/*
@@ -137,7 +139,8 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
*/
arm_cpuidle_save_irq_context(&context);
- ct_cpuidle_enter();
+ if (idle)
+ ct_cpuidle_enter();
if (__cpu_suspend_enter(&state)) {
/* Call the suspend finisher */
@@ -153,9 +156,11 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
if (!ret)
ret = -EOPNOTSUPP;
- ct_cpuidle_exit();
+ if (idle)
+ ct_cpuidle_exit();
} else {
- ct_cpuidle_exit();
+ if (idle)
+ ct_cpuidle_exit();
__cpu_suspend_exit();
}
base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff
--
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).
See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
You can comment on the patch as usual, syzbot will try to address
the comments and send a new version of the patch if necessary.
syzbot engineers can be reached at [email protected].