Re: ACPI enable on Thinkpad X60 hangs when temperatures are high

From: Pavel Machek
Date: Mon May 27 2019 - 06:40:44 EST


Hi!

> > > So if you compile a kernel, then reboot, boot will hang after "Freeing SMP
> > > alternatives memory" (and then wastes power, making thermal situation even worse).
> >
> > Normally, next message is "smpboot: CPU0: Genuine Intel...".
> >
> > I added some printks, and check_bugs() returns. Then it goes to ACPI and never
> > comes back...
> >
> > kernel-parameters.txt points to Documentation/acpi/debug.txt, but that one does not exist.
> >
> > Any ideas what debugging parameters to use for ACPI? I either get nothing or
> > so much that machine does not boot...
>
> I ended up adding printks...
>
> It hangs in acpi_hw_set_mode().
>
> ACPI enable: set mode: acpi
> ACPI: hw_set_mode
> ACPI: hw_set_mode mode switch
> ACPI: write_port?
> ACPI: os write port
>
> we write to the port but that never returns.
>
> I assume SMM is doing its magic at that point. Any ideas how to debug it further?
>
> Is it possible that it is some kind of screaming interrupt?

Exact position of debug prints was this:

diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index e528fe5..e9bb627 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -37,16 +37,20 @@ acpi_status acpi_enable(void)

/* ACPI tables must be present */

+ printk("ACPI enable: 1\n");
+
if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) {
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}

+ printk("ACPI enable: 2\n");
/* If the Hardware Reduced flag is set, machine is always in acpi mode */

if (acpi_gbl_reduced_hardware) {
return_ACPI_STATUS(AE_OK);
}

+ printk("ACPI enable: 3\n");
/* Check current mode */

if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
@@ -57,13 +61,17 @@ acpi_status acpi_enable(void)

/* Transition to ACPI mode */

+ printk("ACPI enable: set mode: acpi\n");
status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
+ printk("ACPI enable: set mode: acpi done\n");
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO,
"Could not transition to ACPI mode"));
return_ACPI_STATUS(status);
}

+ printk("ACPI enable: sanity check\n");
+
/* Sanity check that transition succeeded */

for (retry = 0; retry < 30000; ++retry) {
@@ -76,6 +84,8 @@ acpi_status acpi_enable(void)
acpi_os_stall(100); /* 100 usec */
}

+ printk("ACPI enable: sanity check done\n");
+
ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
}
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index 926f7e0..e8063f9 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -38,6 +38,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
return_ACPI_STATUS(AE_OK);
}

+ printk("ACPI: hw_set_mode\n");
/*
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
@@ -62,13 +63,17 @@ acpi_status acpi_hw_set_mode(u32 mode)
return_ACPI_STATUS(AE_OK);
}

+ printk("ACPI: hw_set_mode mode switch\n");
switch (mode) {
case ACPI_SYS_MODE_ACPI:

/* BIOS should have disabled ALL fixed and GP events */

+ printk("ACPI: write_port?\n");
status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_enable, 8);
+ printk("ACPI: write_port done.\n");
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable ACPI mode\n"));
break;
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index cd57615..b3ed022 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -262,7 +262,9 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)

status = acpi_hw_validate_io_request(address, width);
if (ACPI_SUCCESS(status)) {
+ printk("ACPI: os write port\n");
status = acpi_os_write_port(address, value, width);
+ printk("ACPI: os write port done\n");
return (status);
}

diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
index 9f3b1e3..4418fa9 100644
--- a/drivers/acpi/acpica/utxfinit.c
+++ b/drivers/acpi/acpica/utxfinit.c
@@ -45,6 +45,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());

/* Initialize the OS-Dependent layer */
+ printk("ACPI: os initialize\n");

status = acpi_os_initialize();
if (ACPI_FAILURE(status)) {
@@ -53,6 +54,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
}

/* Initialize all globals used by the subsystem */
+ printk("ACPI: globals\n");

status = acpi_ut_init_globals();
if (ACPI_FAILURE(status)) {
@@ -62,6 +64,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
}

/* Create the default mutex objects */
+ printk("ACPI: mutex\n");

status = acpi_ut_mutex_initialize();
if (ACPI_FAILURE(status)) {
@@ -70,6 +73,8 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
return_ACPI_STATUS(status);
}

+ printk("ACPI: ns root\n");
+
/*
* Initialize the namespace manager and
* the root of the namespace tree
@@ -82,6 +87,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
}

/* Initialize the global OSI interfaces list with the static names */
+ printk("ACPI: interfaces\n");

status = acpi_ut_initialize_interfaces();
if (ACPI_FAILURE(status)) {
@@ -90,6 +96,8 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
return_ACPI_STATUS(status);
}

+ printk("ACPI: all done, all ok\n");
+
return_ACPI_STATUS(AE_OK);
}

@@ -113,6 +121,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)

ACPI_FUNCTION_TRACE(acpi_enable_subsystem);

+ printk("ACPI: enable subsys\n");
/*
* The early initialization phase is complete. The namespace is loaded,
* and we can now support address spaces other than Memory, I/O, and
@@ -124,19 +133,24 @@ acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)

/* Enable ACPI mode */

+ printk("ACPI: go to ACPI\n");
if (!(flags & ACPI_NO_ACPI_ENABLE)) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"[Init] Going into ACPI mode\n"));

+ printk("ACPI: get mode\n");
acpi_gbl_original_mode = acpi_hw_get_mode();

+ printk("ACPI: enable\n");
status = acpi_enable();
+ printk("ACPI: enable done\n");
if (ACPI_FAILURE(status)) {
ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
return_ACPI_STATUS(status);
}
}

+ printk("ACPI: map FACS\n");
/*
* Obtain a permanent mapping for the FACS. This is required for the
* Global Lock and the Firmware Waking Vector
@@ -149,6 +163,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)
}
}

+ printk("ACPI: event handling\n");
/*
* Initialize ACPI Event handling (Fixed and General Purpose)
*
@@ -173,6 +188,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)
}
}

+ printk("ACPI: SCI handler\n");
/*
* Install the SCI handler and Global Lock handler. This completes the
* hardware initialization.
@@ -188,6 +204,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)
}
#endif /* !ACPI_REDUCED_HARDWARE */

+ printk("ACPI: enable done\n");
return_ACPI_STATUS(status);
}

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index eec263c..f712151 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1105,9 +1105,12 @@ void __init acpi_subsystem_init(void)
{
acpi_status status;

+ printk("ACPI: subsystem init\n");
+
if (acpi_disabled)
return;

+ printk("ACPI: enable subsystem\n");
status = acpi_enable_subsystem(~ACPI_NO_ACPI_ENABLE);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
@@ -1121,6 +1124,7 @@ void __init acpi_subsystem_init(void)
*/
regulator_has_full_constraints();
}
+ printk("ACPI: init done\n");
}

static acpi_status acpi_bus_table_handler(u32 event, void *table, void *context)


--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

Attachment: signature.asc
Description: Digital signature