Re: [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check

From: Sergey Lebedev

Date: Sun Aug 30 2026 - 11:17:08 EST


Hi Vladimir, Marcel, Luiz,

This patch is four months old and has had no reply other than the CI
bot. It fixes a real failure. Here is a report from the field and a
test of the patch itself.

Hardware: Microsoft Surface Pro 11 (Intel, Lunar Lake), Intel BE201,
8086:a876 rev 10, firmware timestamp 2026.8 buildtype 1 build 113003,
SHA1 0x08f159a0.

The failure, as it happened here on Ubuntu 7.0.0-28 before any
workaround existed:

Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 0
Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 1
Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 2
btintel_pcie 0000:00:14.7: PM: pci_pm_suspend(): btintel_pcie_suspend [btintel_pcie] returns -16
btintel_pcie 0000:00:14.7: PM: dpm_run_callback(): pci_pm_suspend returns -16
btintel_pcie 0000:00:14.7: PM: failed to suspend async: error -16
PM: Some devices failed to suspend, or early wake event detected

One device returning -EBUSY aborts the whole system suspend, so the
machine simply does not sleep. The workaround in use here since then
unloads btintel_pcie from a systemd sleep hook.

On the frequency I have to be honest rather than useful: it failed on
2 of the 3 suspends attempted before the workaround was installed, and
this week, on 7.0.0-30 with the workaround disabled, it succeeded 7
times out of 7 (3 of those with an LE scan running). Same firmware,
and no btintel_pcie change between the two kernels. So I cannot give
you a reproduction rate, and I am not going to invent one.

What I could do instead is exercise the exact path your patch touches,
deterministically. Method, so it can be judged:

- built v7.0 drivers/bluetooth/btintel_pcie.c out of tree against the
running kernel's headers, unmodified apart from the debug knob
below, and confirmed it loads and works;

- added a debug-only module parameter that returns from
btintel_pcie_msix_gp0_handler() before the boot_stage_cache
refresh, and only while alive_intr_ctxt is BTINTEL_PCIE_D0. That
leaves boot_stage_cache stale and gp0_received false, which is
precisely the state a genuinely missed alive interrupt leaves
behind, while the controller itself still reaches D3.

Without your patch, the emulated missed interrupt reproduces the
production failure exactly:

Timeout (200 ms) on alive interrupt for D2 entry, retry count 0
Timeout (200 ms) on alive interrupt for D2 entry, retry count 1
Timeout (200 ms) on alive interrupt for D2 entry, retry count 2
btintel_pcie 0000:00:14.7: PM: failed to suspend async: error -16
PM: Some devices failed to suspend, or early wake event detected

With your patch applied to that same build, and nothing else changed:

PM: suspend entry (s2idle)
Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 0
PM: suspend exit

One timeout, then the re-read observes D3, set_dxstate() returns 0, and
the system suspends and resumes normally. That is the difference the
two added lines make.

The debug knob is a test fixture, not a proposal; I am happy to send it
to anyone who wants to reproduce this.

Worth noting that btintel_pcie_set_dxstate() is byte-identical in v7.0
and v7.1-rc7, so this is current, not historical.

Tested-by: Sergey Lebedev <lsa.uz@xxxxx>

I have the hardware and can re-test any revision of this patch.

Thanks,
Sergey