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