Trying to fix suspend on kernel 4.19.325 - fix kernel panic caused by while loop
Hi,
I have a device running kernel 4.19.325, and it keeps waking up from suspend right after entering it (and in dmesg it says "Resume cause unknown"). So, I am trying to force it to stay in suspend until it receives an IRQ (which is what should actually wake it up). I have added this inside suspend_test function in kernel/power/suspend.c:
#ifdef CONFIG_ISHSLEEP_SUSPEND
#ifndef CONFIG_PM_DEBUG
int pm_test_level = TEST_CORE;
if (pm_test_level == level) {
while (true) {
if (ishacker_system_irq_wakeup_actual_get())
break;
}
return 1;
}
#endif /* CONFIG_PM_DEBUG */
#endif /* CONFIG_ISHSLEEP_SUSPEND */
So the complete function looks like this:
static int suspend_test(int level)
{
#ifdef CONFIG_PM_DEBUG
if (pm_test_level == level) {
pr_info("suspend debug: Waiting for %d second(s).\n",
pm_test_delay);
mdelay(pm_test_delay * 1000);
return 1;
}
#endif /* !CONFIG_PM_DEBUG */
#ifdef CONFIG_ISHSLEEP_SUSPEND
#ifndef CONFIG_PM_DEBUG
int pm_test_level = TEST_CORE;
if (pm_test_level == level) {
while (true) {
if (ishacker_system_irq_wakeup_actual_get())
break;
}
return 1;
}
#endif /* CONFIG_PM_DEBUG */
#endif /* CONFIG_ISHSLEEP_SUSPEND */
return 0;
}
CONFIG_ISHSLEEP_SUSPEND is enabled in the defconfig, and ishacker_system_irq_wakeup_actual_get() returns the value of bool ishacker_system_irq_wakeup_actual, which is set to true inside pm_system_irq_wakeup function in drivers/base/power/wakeup.c:
void pm_system_irq_wakeup(unsigned int irq_number)
{
if (pm_wakeup_irq == 0) {
struct irq_desc *desc;
const char *name = "null";
desc = irq_to_desc(irq_number);
if (desc == NULL)
name = "stray irq";
else if (desc->action && desc->action->name)
name = desc->action->name;
log_irq_wakeup_reason(irq_number);
#ifdef CONFIG_ISHSLEEP_SUSPEND
ishacker_system_irq_wakeup_actual = true;
#endif
pr_warn("%s: %d triggered %s\n", __func__, irq_number, name);
pm_wakeup_irq = irq_number;
pm_system_wakeup();
}
}
ishacker_system_irq_wakeup_actual is set to false again (using a function) in the pm_suspend function (in kernel/power/suspend.c):
pr_info("suspend entry (%s)\n", mem_sleep_labels[state]);
#ifdef CONFIG_ISHSLEEP_SUSPEND
ishacker_system_irq_wakeup_actual_set(false);
#endif
I am using these functions because I can't export the variables through my header file without running into duplicate symbol errors during linking, and I don't want to use extern. The functions and bools are defined in drivers/base/power/wakeup.c, they are nothing special:
#ifdef CONFIG_ISHSLEEP_SUSPEND
bool ishacker_system_irq_wakeup_actual = false;
bool ishacker_system_irq_wakeup_actual_get(void) {
return ishacker_system_irq_wakeup_actual;
}
void ishacker_system_irq_wakeup_actual_set(bool val) {
ishacker_system_irq_wakeup_actual = val;
}
#endif
The problem is that the kernel panics and the device reboots when I put it to suspend, and when I check /sys/fs/pstore there are no console-ramoopss (which means I can't get the panic log). Also, I noticed that if I use mdelay(5000) instead of that while loop just like in CONFIG_PM_DEBUG's suspend test mode, the device DOES stay in suspend for those 5 seconds, and then it wakes up. There is no kernel panic. But during these 5 seconds, I also cannot wake it up using the power button (which sends the IRQ), and I want it to stay in suspend UNTIL it receives an IRQ, not just for a fixed number of seconds (which is why I need a while loop).
So, I want to know what exactly is causing the panic, and how to fix it. I'm fairly new to C, so please be patient and forgive me if its some stupid mistake I did with e.g the while loop (lol).
Thanks
Categories
- All Categories
- 179 LFX Mentorship
- 179 LFX Mentorship: Linux Kernel
- 776 Linux Foundation IT Professional Programs
- 384 Cloud Engineer IT Professional Program
- 175 Advanced Cloud Engineer IT Professional Program
- 76 DevOps IT Professional Program - Discontinued
- 7 DevOps & GitOps IT Professional Program
- 103 Cloud Native Developer IT Professional Program
- 7.7K Training Courses & Learning Paths
- 17 AI & ML Training
- 2 Blockchain & Decentralized Identity Training
- 44 Cloud & Containers Training
- 7 Cybersecurity Training
- 4 DevOps & Site-Reliability Training
- 3 Linux Kernel Development Training
- 2 Networking Training
- 2 Open Source Best Practice Training
- 6 System Administration Training
- 1 System Engineering Training
- 6 Web & Application Development Training
- 798 Hardware
- 202 Drivers
- 68 I/O Devices
- 37 Monitors
- 96 Multimedia
- 173 Networking
- 91 Printers & Scanners
- 92 Storage
- 774 Linux Distributions
- 82 Debian
- 68 Fedora
- 24 Linux Mint
- 13 Mageia
- 24 openSUSE
- 151 Red Hat Enterprise
- 32 Slackware
- 13 SUSE Enterprise
- 356 Ubuntu
- 473 Linux System Administration
- 31 Cloud Computing
- 73 Command Line/Scripting
- Github systems admin projects
- 104 Linux Security
- 79 Network Management
- 102 System Management
- 46 Web Management
- 174 Mobile Computing
- 32 Android
- 127 Development
- 1.2K New to Linux
- 1K Getting Started with Linux
- 407 Off Topic
- 128 Introductions
- 35 Study Material
- 1.1K Programming and Development
- 312 Kernel Development
- 729 Software Development
- 1K Software
- 421 Applications
- 183 Command Line
- 5 Compiling/Installing
- 71 Games
- 320 Installation
- Archived
- 183 Small Talk
- 2 LFD140 Class Forum
- 1.4K LFS258 Class Forum
Upcoming Training
-
August 20, 2018
Kubernetes Administration (LFS458)
-
August 20, 2018
Linux System Administration (LFS301)
-
August 27, 2018
Open Source Virtualization (LFS462)
-
August 27, 2018
Linux Kernel Debugging and Security (LFD440)