Skip to content

ACPI thermal zone permanent deadlock: Sleep opcode in _TMP method holds mutex, all thermal kworkers blocked #54

Description

@btdwv

Orange Pi 6 Plus — ACPI Thermal Zone Permanent Deadlock

System Info

Summary

ACPI thermal zone temperature read method (_TMP) executes a Sleep opcode in AML bytecode
while holding the ACPI mutex. The sleeping thread never releases the lock, causing all other
thermal worker threads (9 threads) to deadlock permanently. The system never recovers —
RCU stalls continue for 17+ hours until forced power-off.

Timeline (2026-07-20 ~ 2026-07-21)

Time Event
07-20 21:41:50 System boot (kernel 7.0.0-37-cix)
07-21 02:30:00 First RCU stall detected on CPU 0 — thermal deadlock begins
07-21 02:30:26 9 thermal kworker threads blocked >122 seconds on ACPI semaphore
07-21 02:34:32 systemd-oomd watchdog timeout #1 (SIGABRT)
07-21 02:47:23 systemd-oomd watchdog timeout #2
07-21 03:17:13 systemd-oomd watchdog timeout #3
07-21 04:05:33 systemd-oomd watchdog timeout #4
07-21 05:28:33 systemd-oomd watchdog timeout #5
07-21 10:01:32 systemd-oomd watchdog timeout #6
07-21 02:30 ~ 20:03 ~200 RCU stall events — system permanently degraded
07-21 22:09 Forced reboot by long-pressing power button (~20 hours after deadlock)

Root Cause

The ACPI firmware's thermal zone _TMP method contains AML bytecode that calls Sleep()
while holding the ACPI namespace evaluation mutex. Once the sleeping thread is scheduled out,
it never gets CPU time to release the lock, permanently blocking all subsequent thermal reads.

Deadlock call chain (from all 9 blocked kworker threads):

thermal_zone_device_check
  → __thermal_zone_get_temp → thermal_get_temp → acpi_thermal_get_temperature
    → acpi_evaluate_integer → acpi_evaluate_object → acpi_ns_evaluate
      → acpi_ps_execute_method → acpi_ps_parse_aml
        → acpi_ds_exec_end_op → acpi_ex_opcode_1A_0T_0R
          → acpi_ex_system_do_sleep → acpi_os_sleep
            ↑ holds ACPI mutex, sleeps indefinitely

Root holder: kworker/u48:4 (PID 49624) — all other thermal workers blocked on:

INFO: task kworker/u48:X blocked on a semaphore likely last held by task kworker/u48:4:49624

Blocked Tasks (all at 02:30:26, all in thermal_events workqueue)

Task PID Status
kworker/u48:0 49494 D (blocked >122s)
kworker/u48:1 46730 D (blocked >122s)
kworker/u48:2 36847 D (blocked >122s)
kworker/u48:3 48107 D (blocked >122s)
kworker/u48:4 49624 D — root holder
kworker/u48:5 43983 D (blocked >122s)
kworker/u48:6 51836 D (blocked >122s)
kworker/u48:7 51837 D (blocked >122s)
kworker/u48:8 51838 D (blocked >122s)

RCU Stall Pattern

The RCU stalls continued continuously from 02:30 to 20:03 (17.5 hours), indicating the
system was permanently degraded but not fully dead — userspace processes could still
run (slowly) on non-thermal CPUs, but the kernel scheduling was severely impaired.

Key Observations

  1. Permanent deadlock: The ACPI mutex is never released. No self-recovery is possible.
  2. Not load-dependent: System had been running idle for ~4.75 hours before the crash.
  3. Not reproducible on demand: The system ran fine for those hours before the deadlock
    triggered, suggesting a rare timing condition or ACPI runtime variable state.
  4. ACPI firmware bug: The AML bytecode should not call Sleep() while holding the thermal
    zone evaluation lock. This is a CIX BIOS/firmware defect.

Related Issues

  • #8 — ACPI LPI / CPPC; deep CPU idle states may not be entered
  • #24 — Kernel Error During BOOT on Orange PI 6 (BIOS 1.4)

Attachments

  • syslog — Full system log (18MB, covers July 19–21)
  • kern.log — Full kernel log (5.1MB)
  • systemd-oomd.crash — systemd-oomd crash dump (219KB)
  • udevadm.crash — udevadm crash dump (2.9MB)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions