https://bugzilla.kernel.org/show_bug.cgi?id=221842

            Bug ID: 221842
           Summary: ACPI: AB/BA deadlock between kec_query
                    (acpi_ec_event_processor) and kacpi_notify
                    (acpi_battery_notify) workers on the AML mutex - HP
                    ZBook Firefly 14 G10
           Product: ACPI
           Version: 2.5
          Hardware: Intel
                OS: Linux
            Status: NEW
          Severity: high
          Priority: P3
         Component: EC
          Assignee: [email protected]
          Reporter: [email protected]
        Regression: No

Created attachment 310583
  --> https://bugzilla.kernel.org/attachment.cgi?id=310583&action=edit
Full ACPI table dump (MSDM body removed - OEM Windows key)

AB/BA deadlock between the kec_query and kacpi_notify workqueue workers on the
AML mutex, on an HP ZBook Firefly 14 inch G10. The machine hard-hangs every
8-23
days. Once wedged, every subsequent EC transaction blocks in uninterruptible
sleep and the count grows without bound until the machine is unusable; recovery
is only by forced power-off and the journal ends mid-line each time.

Six occurrences captured with per-boot journals, and the last two with a
30-second-interval watchdog sampling GPE rate and D-state task count, so the
onset window is bounded to 30 seconds and the precursor is captured.


THE DEADLOCK
============

Two workers each hold the mutex the other needs:

  - kec_query / acpi_ec_event_processor, evaluating an EC _Qxx query method,
    blocked in acpi_ex_acquire_mutex -> acpi_os_wait_semaphore

  - kacpi_notify / acpi_os_execute_deferred -> acpi_battery_notify ->
    acpi_battery_refresh -> acpi_battery_get_info, blocked on the EC/AML mutex
    the query worker holds

On the most recent occurrence the kernel names the cycle itself. Every other
blocked worker reports being blocked on a semaphore last held by
kworker/0:0:2924563, while kworker/0:0:2924563 reports blocked on one last held
by kworker/2:2:2931861:

  INFO: task kworker/2:1:2864589 blocked for more than 61 seconds.
        Tainted: G           OE       7.0.0-28-generic #28~24.04.1-Ubuntu
  Workqueue: kec_query acpi_ec_event_processor
  Call Trace:
   __schedule+0x2d0/0x660
   schedule+0x27/0x90
   schedule_timeout+0x104/0x110
   ___down_common+0x14c/0x200
   __down_common+0x5a/0x150
   __down_timeout+0x16/0x30
   down_timeout+0x6a/0x70
   acpi_os_wait_semaphore+0x7c/0x1c0
   acpi_ex_system_wait_mutex+0xdf/0x140
   acpi_ex_acquire_mutex_object+0x68/0x170
   acpi_ex_acquire_mutex+0x8c/0x2d0
   acpi_ex_opcode_2A_0T_1R+0x172/0x1f0
   acpi_ds_exec_end_op+0x1bb/0x970
   acpi_ps_parse_loop+0x276/0x780
   acpi_ps_parse_aml+0x226/0x600
   acpi_ps_execute_method+0x172/0x3e0
   acpi_ns_evaluate+0x175/0x5f0
   acpi_evaluate_object+0x213/0x490
   acpi_ec_event_processor+0xe6/0x140
   process_one_work+0x1af/0x430
  INFO: task kworker/2:1:2864589 blocked on a semaphore likely last held by
        task kworker/0:0:2924563

This looks like a mutex-acquisition-ordering bug in the platform DSDT/AML (HP
firmware), exposed whenever a firmware-initiated EC _Qxx query races an
OS-initiated battery Notify(). I am filing here rather than only with the
vendor
because the kernel currently has no way to break or avoid the cycle, and
because
the unbounded pile-up afterwards may itself be worth addressing.


TIMELINE OF THE MOST RECENT OCCURRENCE (2026-08-06)
===================================================

Watchdog samples every 30 s. gpe6E is the GPE 0x6E (EC) interrupt rate, Dtasks
the count of tasks in uninterruptible sleep.

  [09:02:12] gpe6E=1/s  Dtasks=0
  [09:02:42] gpe6E=5/s  Dtasks=0   <- EC event burst; upower logs battery
                                      99->97->99 at 09:02:38-39
  [09:03:12] gpe6E=1/s  Dtasks=0
  [09:04:12] gpe6E=1/s  Dtasks=0   <- last healthy sample
  [09:04:42] gpe6E=2/s  Dtasks=8   <- deadlock latches inside this 30 s window
  [09:05:12] gpe6E=0/s  Dtasks=12  <- EC stops completing entirely
  [09:15:17] gpe6E=0/s  Dtasks=34     (khungtaskd all-CPU backtrace at
09:15:18)
  [09:42:14] gpe6E=0/s  Dtasks=92     load average 90.29

Note gpe6E drops to exactly 0/s at latch and never recovers: the EC completes
no
further transactions. The load average of 90 is entirely blocked tasks, not CPU
use. The last upower sample ever written is the 09:02:39 battery reading -
upowerd is among the first victims, which is why no further battery state is
recorded.

The trigger is consistently a battery Notify(): a charge-state perturbation
appears in upower within a few minutes of every latch.

On an earlier occurrence (2026-07-28) the same deadlock latched inside the
s2idle suspend-entry window, about 4 s after "PM: suspend entry (s2idle)", most
likely from an AC-removal notify racing suspend. That variant is worse: the
machine never reaches a low-power state. It sat drawing ~8 W sustained in a
closed bag for 84 minutes.


REPRODUCIBILITY
===============

Six occurrences: 2026-06-16, 06-18, 07-11, 07-20, 07-28, 08-06 (gaps 2, 23, 9,
8, 9 days). No deliberate reproducer - it fires on ordinary desktop use,
correlated with battery/AC state changes.

Not a regression. The first three occurred on 6.17.0-35-generic, the last three
on 7.0.0-28-generic, verified per-boot from the journals. Both series affected.


SYSTEM
======

  Machine:  HP ZBook Firefly 14 inch G10 Mobile Workstation PC
  BIOS:     HP V70 Ver. 01.12.01, 2026-05-03 (latest; fwupd reports up to date)
  CPU/GPU:  i7-1355U + NVIDIA RTX A500 (hybrid)
  Kernels:  7.0.0-28-generic and 6.17.0-35-generic (Ubuntu 24.04.4 LTS)
  Cmdline:  ro quiet splash vt.handoff=7  - no ACPI parameters set
  Taint:    12288 = TAINT_OOT_MODULE + TAINT_UNSIGNED_MODULE (NVIDIA DKMS only;
            no warn/oops bits)

On the taint and the distro kernel: this is an Ubuntu kernel with the NVIDIA
DKMS module loaded. NVIDIA appears in none of the six deadlock traces - every
blocked task is an ACPI workqueue worker in drivers/acpi. The decisive artifact
is the acpidump, which comes from firmware and is kernel- and
distro-independent.
I can test a vanilla mainline kernel on request, though given the 8-23 day
interval a negative result would take weeks to mean anything.


WHAT I ALREADY RULED OUT
========================

thermald was the amplifier, and masking it did NOT fix it. ftrace of
acpi_ec_space_handler / submit / complete showed thermald polling DPTF/int340x
thermal-zone AML accounted for 72 of 87 EC operations in a 3-second sample
(call
path: thermald -> acpi_ev_address_space_dispatch -> acpi_ec_space_handler ->
acpi_ec_transaction). An A/B test measured GPE 0x6E at ~17/s with thermald
running vs ~2/s stopped, about 87% of EC traffic. I masked it on 2026-07-20; EC
rate has held at 1-2/s since, and the machine has still deadlocked twice, at 8
and 9 day intervals, both inside the pre-mitigation range. So reducing EC
traffic
~8.5x did not prevent the race - baseline kworker EC activity alone is
sufficient
to hit it. I mention this because "your EC is being hammered by a userspace
poller" is a reasonable first read of the symptom, and it turned out not to be
the cause.

Not a firmware event storm. ftrace of acpi_ec recorded 0 query events with all
samples SCI_EVT=0; the GPE increments are EC completion IRQs from OS-initiated
reads, not spontaneous _Qxx events.

Not fixable by BIOS update. Installed BIOS 01.12.01 is newer than the latest
SoftPaq I could find (01.09.00 / sp158083, Apr 2025), and fwupd reports up to
date.

hung_task_panic would not have captured the suspend-time variant - khungtaskd
is
freezable and that hang is inside the suspend path, so no hung-task report was
emitted for the 2026-07-28 occurrence (verified: zero "INFO: task" lines in
that
boot).


PRIOR ART
=========

The historical attempts to run Notify() handlers off the main
deferred-execution
thread were both reverted, and the stated reason matches what I observe exactly
-
events get caught behind the AML semaphore and the workers pile up until the
system dies:

  b8d35192c55fb055792ff0641408eaaec7c88988
    "ACPI: execute Notify() handlers on new thread"
    reverted in 72945b2b90a5554975b8f72673ab7139d232a121

  37605a6900f6b4d886d995751fcfeef88c4e462c
    "ACPI: created a dedicated workqueue for notify() execution"
    reverted in b976fe19acc565e5137e6f12af7b6633a23e6b7c

The unbounded D-state accumulation after the latch (0 -> 92 blocked tasks in 38
minutes, still climbing when power was cut) looks like the same failure the
second revert describes.


ATTACHMENTS
===========

  acpidump-sanitized.txt          full ACPI table dump (the key artifact;
                                  contains the DSDT with the offending mutex
                                  ordering)
  dmesg-boot-minus-1-sanitized.txt  complete kernel log for the boot that
                                  deadlocked
  hungtask-first-report.txt       first hung-task report at 09:06:05, before
the
                                  all-CPU backtrace noise
  semaphore-summary.txt           every "blocked on a semaphore likely last
held
                                  by" line, showing the cycle
  watchdog-window-2026-08-06.txt  30 s watchdog samples across the latch and
the
                                  following 38 minutes

Two redactions, neither touching anything ACPI-related: the MSDM table body is
removed (it carries the OEM Windows product key), and Wi-Fi MAC/BSSID values in
the kernel log are replaced with <mac-redacted-N> placeholders, consistently
per
unique value. All 39 SSDTs, the DSDT, and the FACP are intact. Happy to supply
anything further on request.


QUESTIONS
=========

1. Is there a supportable way to break or time-bound this cycle from the kernel
   side, or is a DSDT override the only route?

2. Should the post-deadlock pile-up be bounded - should the EC query workqueue
   stop accepting work once a transaction has been stuck past EC_CMD_TIMEOUT,
   rather than accumulating unbounded blocked workers?

3. Is there anything further worth capturing on the next occurrence? I have a
   watchdog in place and can add instrumentation; ramoops is not yet
configured.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

_______________________________________________
acpi-bugzilla mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/acpi-bugzilla

Reply via email to