Re: Pressing the power button causes the device to freeze completely
From: Rafael J. Wysocki
Date: Tue Apr 28 2026 - 13:40:50 EST
On Monday, April 27, 2026 11:49:51 PM CEST Evgeny Sagatov wrote:
> apr 28 00:48:34 srv kernel: ACPI power button event
> apr 28 00:48:34 srv kernel: ACPI event status I/O port number: 1024
>
> пн, 27 апр. 2026 г. в 23:31, Rafael J. Wysocki <rafael@xxxxxxxxxx>:
> >
> > On Monday, April 27, 2026 10:12:33 PM CEST Evgeny Sagatov wrote:
> > > dmesg | grep "frequency scaling"
> > > [ 8.552380] acpi_cpufreq: CPU0: Using I/O space for frequency scaling
> > > [ 8.552386] acpi_cpufreq: CPU0: frequency scaling I/O port number: 2176
> > > [ 8.552478] acpi_cpufreq: CPU1: Using I/O space for frequency scaling
> > > [ 8.552480] acpi_cpufreq: CPU1: frequency scaling I/O port number: 2176
> > > [ 8.552584] acpi_cpufreq: CPU2: Using I/O space for frequency scaling
> > > [ 8.552586] acpi_cpufreq: CPU2: frequency scaling I/O port number: 2176
> > > [ 8.552668] acpi_cpufreq: CPU3: Using I/O space for frequency scaling
> > > [ 8.552670] acpi_cpufreq: CPU3: frequency scaling I/O port number: 2176
The I/O ports that play the role in this issue are separate from each other in
the address space, but that need not mean that they are physically independent.
My current theory is that accessing one of them while an access to the other
one is still in progress may cause the platform to lock up, or there is an
access pattern that causes that to happen.
Let's first test the simplest variant of that theory and see what happens if
all I/O port accesses in acpi_os_write_port() are serialized, which is done
in the patch below (it is a replacement for all of the patches sent so far).
In addition, that patch causes schedutil to use the slow path for updating the
frequency because the I/O space is generally somewhat too slow to be used
from the scheduler context relatively often, but that should not affect the
behavior related to I/O space accesses.
Please check if the system still locks up after pressing the power button
with this patch applied.
---
drivers/acpi/osl.c | 9 +++++++--
drivers/cpufreq/acpi-cpufreq.c | 9 ++++++---
2 files changed, 13 insertions(+), 5 deletions(-)
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -700,8 +700,10 @@ EXPORT_SYMBOL(acpi_os_read_port);
acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
{
- if (!IS_ENABLED(CONFIG_HAS_IOPORT))
- return AE_NOT_IMPLEMENTED;
+#ifdef CONFIG_HAS_IOPORT
+ static DEFINE_RAW_SPINLOCK(acpi_os_write_port_lock);
+
+ guard(raw_spinlock_irqsave)(&acpi_os_write_port_lock);
if (width <= 8) {
outb(value, port);
@@ -715,6 +717,9 @@ acpi_status acpi_os_write_port(acpi_io_a
}
return AE_OK;
+#else
+ return AE_NOT_IMPLEMENTED;
+#endif
}
EXPORT_SYMBOL(acpi_os_write_port);
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -878,6 +878,10 @@ static int acpi_cpufreq_cpu_init(struct
policy->freq_table = freq_table;
perf->state = 0;
+ policy->fast_switch_possible = !acpi_pstate_strict &&
+ !(policy_is_shared(policy) &&
+ policy->shared_type != CPUFREQ_SHARED_TYPE_ANY);
+
switch (perf->control_register.space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
/*
@@ -887,6 +891,8 @@ static int acpi_cpufreq_cpu_init(struct
* unknown and not detectable via IO ports.
*/
policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
+ /* I/O spcase is too slow for fast switching. */
+ policy->fast_switch_possible = false;
break;
case ACPI_ADR_SPACE_FIXED_HARDWARE:
acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
@@ -912,9 +918,6 @@ static int acpi_cpufreq_cpu_init(struct
*/
data->resume = 1;
- policy->fast_switch_possible = !acpi_pstate_strict &&
- !(policy_is_shared(policy) && policy->shared_type != CPUFREQ_SHARED_TYPE_ANY);
-
if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
pr_warn(FW_WARN "P-state 0 is not max freq\n");