Public bug reported:

SUMMARY
On a ThinkPad T16 Gen 4 (type 21QE0023AU, Intel Meteor Lake-P) with BIOS 1.18 
(N4JET28W, DMI "Firmware Revision" 1.13), running Ubuntu 24.04.5 with 
linux-oem-6.17 6.17.0-1033.33, the embedded controller (EC) enters a state 
where it asserts its SCI/GPE 0x6E continuously and every EC query returns event 
0x3E. The DSDT's _Q3E handler calls ^HKEY.MHKQ(0x6013) (thinkpad_acpi: 
TP_HKEY_EV_ALARM_BAT_LIM_CHANGE, "battery charge threshold changed") and then 
Notify(BAT0, 0x80).

Measured with EC driver dynamic debug: Query(0x3e) is the only query
being raised. Rates measured from /sys/firmware/acpi/interrupts/gpe6E:
400-550 events/s with the stock configuration, about 2,400 events/s with
the charge thresholds cleared (0/100). In every measurement there were
no OS-side writes to the EC threshold registers and the AC adapter was
unplugged.

CONSEQUENCES
1. Every Notify(BAT0, 0x80) becomes a kacpi_notify work item running 
acpi_battery_notify(), which serializes on a mutex (mutex_lock at 
acpi_battery_notify+0x38). Inside the critical section the notifier chain 
(acpi_ac_battery_notify -> acpi_ac_get_state -> _PSR) and the battery methods 
(_STA/_BST) each perform EC transactions, which are slow because the EC is 
saturated by its own event storm. The kacpi_notify pool grows to 16,384 
kworkers, all in D state waiting for that mutex. The hung-task detector fires 
("blocked for more than 122 seconds"), and the load average sits at 
16,387-16,389 with the CPU idle.
2. Every other ACPI notification starves behind that backlog. Visible effect: 
UCSI commands time out ("ucsi_acpi USBC000:00: ucsi_handle_connector_change: 
GET_CONNECTOR_STATUS failed (-110)"), so a device plugged into a USB-C port is 
never processed. Unbinding ucsi_acpi hangs forever in 
acpi_os_wait_events_complete -> __flush_workqueue because kacpi_notify can 
never drain.
3. 8.2 million SCI interrupts in this boot (/proc/interrupts IRQ 9). 
/proc/irq/9/spurious shows most of the recent ones unhandled (count 75225, 
unhandled 71996) because the EC driver masks the GPE around query processing 
("Polling enabled"/"Polling disabled" in ec.c debug output) while the line 
stays asserted. /sys/firmware/acpi/interrupts/gpe6E alternates between "STS 
enabled unmasked" (hardware EN bit clear while masked) and "EN enabled 
unmasked".

HARDWARE / SOFTWARE
- Lenovo ThinkPad T16 Gen 4, 21QE0023AU; BIOS N4JET28W 1.18 (DMI release date 
06/16/2026), DMI Firmware Revision 1.13; ECDT present (LENOVO TP-N4J, PTEC)
- EC GPE 0x6E (from the ECDT and from Device(EC) _GPE in the DSDT); 
EC_CMD/EC_SC=0x66, EC_DATA=0x62
- Ubuntu 24.04.5 LTS, kernel 6.17.0-1033-oem #33-Ubuntu (linux-oem-6.17 
6.17.0-1033.33), thinkpad_acpi 0.26
- Battery SMP 5B11M90104, 54 cycles; charge thresholds normally 75/80 (applied 
by a udev rule at boot)
- Kernel command line: quiet splash mitigations=auto button.lid_init_state=open
- acpi.ec_* parameters all at defaults (ec_event_clearing=query, 
ec_storm_threshold=8, ec_polling_guard=550, ec_delay=500)

TIMELINE OF THIS BOOT (local time, from rsyslog kern.log; journald had already 
rotated the early entries)
- 21:24 boot. The first kacpi_notify worker that is still stuck today was 
created 4 s after boot, so the backlog started building immediately (the EC 
state appears to survive a warm reboot; see recurrences).
- 21:45-21:48 s2idle suspend/resume; 21:55 suspend; 00:05 resume.
- 00:58 first hung-task reports: kworker/3:20 blocked >122 s in mutex_lock from 
acpi_battery_notify+0x38; "blocked on a mutex likely owned by task 
kworker/2:984", whose trace is ec_guard <- acpi_ec_transaction_unlocked <- 
acpi_ec_space_handler <- ACPICA field read <- acpi_evaluate_integer <- 
acpi_ac_get_state <- acpi_ac_battery_notify <- notifier chain <- 
acpi_battery_notify+0xac.
- Stuck-worker creation histogram (count per hour): 573 (21h), 4,612 (00h), 
4,584 (01h), 3,892 (02h), 2,351 (03h), then a trickle until 10:28; 16,384 total.
- 02:31 and 14:00: ucsi GET_CONNECTOR_STATUS -110 each time a USB-C device was 
connected. The device never enumerated.
- At the time of writing GPE 0x6E has fired 4.65 million times.

WHAT WAS RULED OUT
- Custom OS configuration. This machine has two custom udev rules (one 
re-applies the 75/80 thresholds on power_supply uevents, one switches 
power-profiles-daemon profiles on AC changes) and two small custom services. 
All were removed/stopped (udev reloaded), the thresholds were cleared in the EC 
(0/100), and the AC adapter was unplugged. The event rate did not drop; it rose 
to about 2,400/s. The rules have existed unchanged since February 2026. The 
storms began on 2026-10-09, twelve days after the BIOS 1.18 update 
(2026-09-27), and recurred on 2026-10-24, 2026-10-25, 2026-10-26 and 2026-11-05 
(hung-task reports in kern.log for each). Note: the threshold-rewriting rule 
has no ACTION filter, so during a storm it does re-write the thresholds on 
every change uevent; that was a suspect, but the storm continues identically 
without it.
- The EC still services transactions normally (thinkpad_acpi fan and 
temperature reads return live, changing values). It is the event path that is 
flooded.
- No CPU load, no memory pressure; threads-max far from its limit. The machine 
stays usable apart from the ACPI-notify consumers (USB-C hotplug, battery/AC 
notifications).
- Re-arming GPE 0x6E through /sys/firmware/acpi/interrupts (clear, mask, 
unmask) made no difference.
- A reboot clears the worker backlog, but on 2026-10-26 the storm was back 37 
minutes after boot, and in this boot the backlog was already building 4 seconds 
after boot. An EC reset (power off, adapter out, emergency-reset pinhole) has 
not been tried yet.

REQUEST
This looks like an EC firmware defect in the BIOS 1.18 charge-threshold 
handling: the EC emits "battery charge threshold changed" continuously with no 
host write and with the feature disabled. Filing against the OEM kernel because 
the model is Ubuntu-certified, so that it can be raised with Lenovo. Two 
kernel-side points may deserve hardening regardless of the firmware fix: (a) 
kacpi_notify grows without bound until it saturates and starves every other 
ACPI notify consumer (UCSI, lid, AC); (b) acpi_battery_notify holds its mutex 
across the notifier chain while the chain performs EC transactions, so one slow 
EC turns a notification flood into a 16k-thread pile-up.

RELATED UPSTREAM WORK
"[PATCH 2/2] ACPI: battery: Merge consecutive battery notifications" (Rong 
Zhang, linux-acpi, 26 May 2026, Cc: stable, Closes: kernel bugzilla 221065) 
describes consecutive battery notifications on Lenovo devices causing EC/ACPI 
mutex contention, method timeouts and garbage data, and queues notify events 
into a kfifo serviced by a 10 ms delayed work so that state is re-read and 
power_supply_changed() called once per burst. The running 6.17.0-1033-oem 
kernel does not carry it (no such worker symbols in kallsyms). It would reduce 
the per-event cost here but would not stop the EC from raising the event itself.

ATTACHMENTS (hostname, user name, local paths, VPN interface names, MAC/IP 
addresses and disk UUIDs are redacted; apport-collected data is not attached 
and can be provided on request after review)
- 01-system-summary.txt: DMI (no serials), package versions, battery, ACPI 
interrupt counters, IRQ 9 spurious counters, stuck-worker histogram, load, 
cmdline
- 02-stuck-task-stacks.txt: /proc/PID/stack of the stuck workers and of the 
hung ucsi_acpi unbind; distinct top frames
- 03-kernel-log-this-boot.txt: surviving journal + dmesg ring buffer
- 04-dsdt-ec-gpe-excerpt.txt: Device(EC) header and every _Qxx handler 
including _Q3E
- 05-battery-and-ac-aml-excerpt.txt: BAT0 _STA/_BIF/_BIX/_BST and AC _PSR
- 06-acpi-tables-raw.tar.gz: DSDT, all SSDTs, FACP, ECDT (raw, from 
/sys/firmware/acpi/tables)
- 07-hung-task-reports.txt and 07a-first-hung-task-report-full.txt: all ten 
hung-task reports from kern.log, first one in full
- 08-kern-log-this-boot-full.txt.gz: full kernel log of this boot from rsyslog
- 09-lspci-lsusb.txt

** Affects: linux-oem-6.17 (Ubuntu)
     Importance: Undecided
         Status: New


** Tags: acpi ec thinkpad

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2173062

Title:
  ThinkPad T16 Gen 4, BIOS 1.18: EC fires _Q3E 'battery charge threshold
  changed' at 500-2400/s; kacpi_notify saturates (16,384 D-state
  workers, load 16k), USB-C/UCSI hotplug dead

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux-oem-6.17/+bug/2173062/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to