Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
@ 2026-05-07 20:34 Vladimir V. Kondratyev
  2026-05-07 21:06 ` bluez.test.bot
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: Vladimir V. Kondratyev @ 2026-05-07 20:34 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Chandrashekar Devegowda, Kiran K, Paul Menzel, Arnd Bergmann,
	linux-bluetooth, linux-kernel, Vladimir V. Kondratyev

btintel_pcie_set_dxstate() falls back to checking the controller state via
btintel_pcie_in_d3/d0() when the alive interrupt is missed. However, these
helpers read boot_stage_cache, which is only updated by the interrupt
handler. As such, if the interrupt was missed, the cache is stale and the
fallback check always fails, exhausting all retries and returning -EBUSY,
causing suspend to abort.

The fix involves re-reading the hardware register before the fallback state
check, consistent with btintel_pcie_resume().

Fixes: e57362f4911b ("Bluetooth: btintel_pcie: Add support for _suspend() / _resume()")

Signed-off-by: Vladimir V. Kondratyev <vladimirkondratyev2@gmail.com>
---
 drivers/bluetooth/btintel_pcie.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index fda474406003..7fca8eea6e01 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -2778,9 +2778,13 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
 					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
 
 		/* A hardware bug may cause the alive interrupt to be missed.
-		 * Check if the controller reached the expected state and retry
-		 * the operation only if it hasn't.
+		 * Refresh boot_stage_cache from hardware since it is only
+		 * updated by the interrupt handler, then check if the
+		 * controller reached the expected state and retry the
+		 * operation only if it hasn't.
 		 */
+		data->boot_stage_cache = btintel_pcie_rd_reg32(data,
+							       BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
 		if (dxstate == BTINTEL_PCIE_STATE_D0) {
 			if (btintel_pcie_in_d0(data))
 				return 0;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* RE: Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-05-07 20:34 [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check Vladimir V. Kondratyev
@ 2026-05-07 21:06 ` bluez.test.bot
  2026-09-01 20:37 ` [PATCH] " Vladimir V. Kondratyev
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: bluez.test.bot @ 2026-05-07 21:06 UTC (permalink / raw)
  To: linux-bluetooth, vladimirkondratyev2

[-- Attachment #1: Type: text/plain, Size: 882 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1091276

---Test result---

Test Summary:
CheckPatch                    PASS      0.69 seconds
GitLint                       PASS      0.30 seconds
SubjectPrefix                 PASS      0.11 seconds
BuildKernel                   PASS      27.57 seconds
CheckAllWarning               PASS      30.23 seconds
CheckSparse                   PASS      28.95 seconds
BuildKernel32                 PASS      27.07 seconds
TestRunnerSetup               PASS      582.94 seconds
IncrementalBuild              PASS      25.20 seconds



https://github.com/bluez/bluetooth-next/pull/155

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
@ 2026-08-30 15:15 Sergey Lebedev
  0 siblings, 0 replies; 19+ messages in thread
From: Sergey Lebedev @ 2026-08-30 15:15 UTC (permalink / raw)
  To: Vladimir V. Kondratyev, Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Chandrashekar Devegowda, Kiran K, Tedd Ho-Jeong An, Paul Menzel,
	Arnd Bergmann, linux-bluetooth, linux-kernel

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@pm.me>

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

Thanks,
Sergey


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-05-07 20:34 [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check Vladimir V. Kondratyev
  2026-05-07 21:06 ` bluez.test.bot
@ 2026-09-01 20:37 ` Vladimir V. Kondratyev
  2026-09-01 22:36   ` bluez.test.bot
  2026-09-02  5:35   ` [PATCH] " Paul Menzel
  2026-09-03 14:29 ` [PATCH v3] " Vladimir V. Kondratyev
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 19+ messages in thread
From: Vladimir V. Kondratyev @ 2026-09-01 20:37 UTC (permalink / raw)
  To: marcel, luiz.dentz, linux-bluetooth, linux-kernel
  Cc: Vladimir V. Kondratyev, Sergey Lebedev

btintel_pcie_set_dxstate() falls back to checking the controller state via
btintel_pcie_in_d3/d0() when the alive interrupt is missed. However, these
helpers read boot_stage_cache, which is only updated by the interrupt
handler. As such, if the interrupt was missed, the cache is stale and the
fallback check always fails, exhausting all retries and returning -EBUSY,
causing suspend to abort.

The fix involves re-reading the hardware register before the fallback state
check, consistent with btintel_pcie_resume().

Fixes: e57362f4911b ("Bluetooth: btintel_pcie: Add support for _suspend() / _resume()")

Signed-off-by: Vladimir V. Kondratyev <vladimirkondratyev2@gmail.com>
Tested-by: Sergey Lebedev <lsa.uz@pm.me>
---
 drivers/bluetooth/btintel_pcie.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index fda474406003..7fca8eea6e01 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -2778,9 +2778,13 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
 					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
 
 		/* A hardware bug may cause the alive interrupt to be missed.
-		 * Check if the controller reached the expected state and retry
-		 * the operation only if it hasn't.
+		 * Refresh boot_stage_cache from hardware since it is only
+		 * updated by the interrupt handler, then check if the
+		 * controller reached the expected state and retry the
+		 * operation only if it hasn't.
 		 */
+		data->boot_stage_cache = btintel_pcie_rd_reg32(data,
+							       BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
 		if (dxstate == BTINTEL_PCIE_STATE_D0) {
 			if (btintel_pcie_in_d0(data))
 				return 0;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* RE: Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-01 20:37 ` [PATCH] " Vladimir V. Kondratyev
@ 2026-09-01 22:36   ` bluez.test.bot
  2026-09-02  5:35   ` [PATCH] " Paul Menzel
  1 sibling, 0 replies; 19+ messages in thread
From: bluez.test.bot @ 2026-09-01 22:36 UTC (permalink / raw)
  To: linux-bluetooth, vladimirkondratyev2

[-- Attachment #1: Type: text/plain, Size: 1181 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1155660

---Test result---

Test Summary:
CheckPatch                    PASS      1.17 seconds
VerifyFixes                   PASS      0.10 seconds
VerifySignedoff               PASS      0.10 seconds
GitLint                       PASS      0.26 seconds
SubjectPrefix                 PASS      0.09 seconds
BuildKernel                   PASS      25.84 seconds
CheckAllWarning               PASS      28.20 seconds
CheckSparse                   PASS      27.63 seconds
BuildKernel32                 PASS      24.69 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      457.25 seconds
IncrementalBuild              PASS      23.96 seconds

Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found


https://github.com/bluez/bluetooth-next/pull/683

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-01 20:37 ` [PATCH] " Vladimir V. Kondratyev
  2026-09-01 22:36   ` bluez.test.bot
@ 2026-09-02  5:35   ` Paul Menzel
  2026-09-02  7:24     ` Sergey Lebedev
  2026-09-02  9:30     ` Sergey Lebedev
  1 sibling, 2 replies; 19+ messages in thread
From: Paul Menzel @ 2026-09-02  5:35 UTC (permalink / raw)
  To: Vladimir V. Kondratyev
  Cc: marcel, luiz.dentz, linux-bluetooth, linux-kernel, Sergey Lebedev,
	Chandrashekar Devegowda, Kiran K

[Cc: +Chandrashekar, +Kiran]

Dear Vladimir,


Thank you for your patch.

Am 01.09.26 um 22:37 schrieb Vladimir V. Kondratyev:
> btintel_pcie_set_dxstate() falls back to checking the controller state via
> btintel_pcie_in_d3/d0() when the alive interrupt is missed. However, these
> helpers read boot_stage_cache, which is only updated by the interrupt
> handler. As such, if the interrupt was missed, the cache is stale and the
> fallback check always fails, exhausting all retries and returning -EBUSY,
> causing suspend to abort.

Can you reproduce this on real hardware?

> The fix involves re-reading the hardware register before the fallback state
> check, consistent with btintel_pcie_resume().
> 
> Fixes: e57362f4911b ("Bluetooth: btintel_pcie: Add support for _suspend() / _resume()")
> 
> Signed-off-by: Vladimir V. Kondratyev <vladimirkondratyev2@gmail.com>
> Tested-by: Sergey Lebedev <lsa.uz@pm.me>
> ---
>   drivers/bluetooth/btintel_pcie.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
> index fda474406003..7fca8eea6e01 100644
> --- a/drivers/bluetooth/btintel_pcie.c
> +++ b/drivers/bluetooth/btintel_pcie.c
> @@ -2778,9 +2778,13 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
>   					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
>   
>   		/* A hardware bug may cause the alive interrupt to be missed.
> -		 * Check if the controller reached the expected state and retry
> -		 * the operation only if it hasn't.
> +		 * Refresh boot_stage_cache from hardware since it is only
> +		 * updated by the interrupt handler, then check if the
> +		 * controller reached the expected state and retry the
> +		 * operation only if it hasn't.

Re-flow for less lines?

>   		 */
> +		data->boot_stage_cache = btintel_pcie_rd_reg32(data,
> +							       BTINTEL_PCIE_CSR_BOOT_STAGE_REG);

To me it sounds strange, that a register name *boot stage* should change 
after the boot. ;-)

>   		if (dxstate == BTINTEL_PCIE_STATE_D0) {
>   			if (btintel_pcie_in_d0(data))
>   				return 0;


Kind regards,

Paul

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-02  5:35   ` [PATCH] " Paul Menzel
@ 2026-09-02  7:24     ` Sergey Lebedev
  2026-09-02  8:38       ` Paul Menzel
  2026-09-02  9:30     ` Sergey Lebedev
  1 sibling, 1 reply; 19+ messages in thread
From: Sergey Lebedev @ 2026-09-02  7:24 UTC (permalink / raw)
  To: Paul Menzel
  Cc: Vladimir V . Kondratyev, Marcel Holtmann, Luiz Augusto von Dentz,
	Chandrashekar Devegowda, Kiran K, linux-bluetooth, linux-kernel

Paul,

Two of your three points I can answer from the hardware, since the
Tested-by on this patch is mine.

> Can you reproduce this on real hardware?

Yes. Surface Pro 11 (Intel, Lunar Lake), Intel BE201, 8086:a876 rev 10.
It first appeared in ordinary use, not in a test:

  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 returns -16
  PM: Some devices failed to suspend, or early wake event detected

One device returning -EBUSY aborts the whole system suspend, so the
machine does not sleep at all.

I have to be honest about the rate rather than useful: it failed on 2 of
the 3 suspends I attempted before installing a workaround, and later, on
a newer kernel with the workaround removed, it succeeded 7 times out of 7
with no btintel_pcie change in between. So the spontaneous failure is not
something I can produce on demand.

What I could do was exercise the exact path deterministically. I built
the driver out of tree with one debug-only 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 the cache
stale and gp0_received false — precisely the state a genuinely missed
alive interrupt leaves behind — while the controller still reaches D3.

Without the patch, that reproduces the production failure exactly: three
timeouts, -EBUSY, suspend aborted. With the patch and nothing else
changed: one timeout, the re-read observes D3, set_dxstate() returns 0,
and the system suspends and resumes normally.

Full method and logs are in my earlier message on this thread,
Message-ID <20260830151550.44687-1-lsa.uz@pm.me>.

> To me it sounds strange, that a register name *boot stage* should
> change after the boot. ;-)

It is a fair reaction to the name, but the register genuinely carries
live power state. From the driver's own header:

  #define BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY  (BIT(24))

and both helpers test that one bit and nothing else:

  static bool btintel_pcie_in_d3(struct btintel_pcie_data *data)
  {
      return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY;
  }

  static bool btintel_pcie_in_d0(struct btintel_pcie_data *data)
  {
      return !(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY);
  }

So bit 24 is updated by the controller on every D-state transition, long
after boot. The name describes the register's original purpose rather
than everything Intel later put in it. btintel_pcie_resume() already
re-reads it for exactly this reason, which is what makes the patch's
change consistent rather than novel.

The re-flow is Vladimir's call and I have no opinion on it. If a v3 comes
out of this, I still have the hardware and the test fixture and will
re-run both halves against it.

Thanks,
Sergey


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-02  7:24     ` Sergey Lebedev
@ 2026-09-02  8:38       ` Paul Menzel
  0 siblings, 0 replies; 19+ messages in thread
From: Paul Menzel @ 2026-09-02  8:38 UTC (permalink / raw)
  To: Sergey Lebedev
  Cc: Vladimir V . Kondratyev, Marcel Holtmann, Luiz Augusto von Dentz,
	Chandrashekar Devegowda, Kiran K, linux-bluetooth, linux-kernel

Dear Sergey,


Thank you for your immediate response.

Am 02.09.26 um 09:24 schrieb Sergey Lebedev:

> Two of your three points I can answer from the hardware, since the
> Tested-by on this patch is mine.
> 
>> Can you reproduce this on real hardware?
> 
> Yes. Surface Pro 11 (Intel, Lunar Lake), Intel BE201, 8086:a876 rev 10.
> It first appeared in ordinary use, not in a test:
> 
>    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 returns -16
>    PM: Some devices failed to suspend, or early wake event detected
> 
> One device returning -EBUSY aborts the whole system suspend, so the
> machine does not sleep at all.
> 
> I have to be honest about the rate rather than useful: it failed on 2 of
> the 3 suspends I attempted before installing a workaround, and later, on
> a newer kernel with the workaround removed, it succeeded 7 times out of 7
> with no btintel_pcie change in between. So the spontaneous failure is not
> something I can produce on demand.
> 
> What I could do was exercise the exact path deterministically. I built
> the driver out of tree with one debug-only 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 the cache
> stale and gp0_received false — precisely the state a genuinely missed
> alive interrupt leaves behind — while the controller still reaches D3.
> 
> Without the patch, that reproduces the production failure exactly: three
> timeouts, -EBUSY, suspend aborted. With the patch and nothing else
> changed: one timeout, the re-read observes D3, set_dxstate() returns 0,
> and the system suspends and resumes normally.
> 
> Full method and logs are in my earlier message on this thread,
> Message-ID <20260830151550.44687-1-lsa.uz@pm.me>.

It’d be great if the thread could be referenced via Link: tag, and also 
the problem summarized in the commit message including the log messages.

>> To me it sounds strange, that a register name *boot stage* should
>> change after the boot. ;-)
> 
> It is a fair reaction to the name, but the register genuinely carries
> live power state. From the driver's own header:
> 
>    #define BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY  (BIT(24))
> 
> and both helpers test that one bit and nothing else:
> 
>    static bool btintel_pcie_in_d3(struct btintel_pcie_data *data)
>    {
>        return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY;
>    }
> 
>    static bool btintel_pcie_in_d0(struct btintel_pcie_data *data)
>    {
>        return !(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY);
>    }
> 
> So bit 24 is updated by the controller on every D-state transition, long
> after boot. The name describes the register's original purpose rather
> than everything Intel later put in it. btintel_pcie_resume() already
> re-reads it for exactly this reason, which is what makes the patch's
> change consistent rather than novel.

Maybe a comment could be added above the macro definition.

> The re-flow is Vladimir's call and I have no opinion on it. If a v3 comes
> out of this, I still have the hardware and the test fixture and will
> re-run both halves against it.

Awesome.

Also note, gemini/gemini-3.1-pro-preview found the same issue in a 
different review [1].


Kind regards,

Paul


[1]: 
https://sashiko.dev/#/patchset/20260902042840.2432862-1-ravindra%40intel.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-02  5:35   ` [PATCH] " Paul Menzel
  2026-09-02  7:24     ` Sergey Lebedev
@ 2026-09-02  9:30     ` Sergey Lebedev
  1 sibling, 0 replies; 19+ messages in thread
From: Sergey Lebedev @ 2026-09-02  9:30 UTC (permalink / raw)
  To: Paul Menzel; +Cc: Vladimir V . Kondratyev, Ravindra, linux-bluetooth

Paul,

Thank you for the pointer — it was the useful part of your mail.

Ravindra's patch changes the same function, and the two turn out to fix
different halves of one failure: his makes a *late* alive interrupt count
by moving the flag out of the retry loop, while Vladimir's makes a
*missing* one survivable, because the fallback check still reads the
stale boot_stage_cache. The hunks also sit on adjacent lines, so whichever
lands second will need a rebase.

I have followed that up in Ravindra's thread rather than here, since it
concerns his patch:

  Message-ID <20260902091021.20160-1-lsa.uz@pm.me>

There I report what our test fixture does under each patch, and offer to
assemble the two as a series if both authors would rather have it that way.

Your other two points — the Link: tag with a fuller commit message, and a
comment above the macro definition — are Vladimir's to act on, and I have
no opinion to add beyond agreeing they would help.

Thanks,
Sergey


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-05-07 20:34 [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check Vladimir V. Kondratyev
  2026-05-07 21:06 ` bluez.test.bot
  2026-09-01 20:37 ` [PATCH] " Vladimir V. Kondratyev
@ 2026-09-03 14:29 ` Vladimir V. Kondratyev
  2026-09-03 14:36   ` Paul Menzel
  2026-09-03 14:47   ` [v3] " bluez.test.bot
  2026-09-03 15:35 ` [PATCH v3] " Vladimir V. Kondratyev
  2026-09-03 19:22 ` [PATCH v4] " Vladimir V. Kondratyev
  4 siblings, 2 replies; 19+ messages in thread
From: Vladimir V. Kondratyev @ 2026-09-03 14:29 UTC (permalink / raw)
  To: marcel, luiz.dentz, pmenzel, chandrashekar.devegowda, arnd,
	kiran.k, linux-bluetooth, linux-kernel, lsa.uz
  Cc: Vladimir V. Kondratyev

btintel_pcie returns -16 (EBUSY) during suspend, causing the entire suspend
operation to abort on Intel Lunar Lake hardware. The system immediately resumes
after every suspend attempt:
  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

btintel_pcie_set_dxstate() falls back to checking the controller state via
btintel_pcie_in_d3/d0() when the alive interrupt is missed. However, these
helpers read boot_stage_cache, which is only updated by the interrupt
handler. As such, if the interrupt was missed, the cache is stale and the
fallback check always fails, exhausting all retries and returning -EBUSY,
causing suspend to abort.

The fix involves re-reading the hardware register before the fallback state
check, consistent with btintel_pcie_resume().

Fixes: e57362f4911b ("Bluetooth: btintel_pcie: Add support for _suspend() / _resume()")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221481
Link: https://lore.kernel.org/linux-bluetooth/20260830151550.44687-1-lsa.uz@pm.me/
Signed-off-by: Vladimir V. Kondratyev <vladimirkondratyev2@gmail.com>
Tested-by: Sergey Lebedev <lsa.uz@pm.me>
---
 drivers/bluetooth/btintel_pcie.c | 8 +++++---
 drivers/bluetooth/btintel_pcie.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index fda474406003..e13631e94214 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -2777,10 +2777,12 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
 					  BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES,
 					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
 
-		/* A hardware bug may cause the alive interrupt to be missed.
-		 * Check if the controller reached the expected state and retry
-		 * the operation only if it hasn't.
+		/* A hardware bug may cause the alive interrupt to be missed. Refresh
+		 * boot_stage_cache from hardware, since only the interrupt handler
+		 * updates it. Finally retry only if the state check still fails.
 		 */
+		data->boot_stage_cache = btintel_pcie_rd_reg32(data,
+							       BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
 		if (dxstate == BTINTEL_PCIE_STATE_D0) {
 			if (btintel_pcie_in_d0(data))
 				return 0;
diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h
index 2db85f71b2f8..f287d1ff8e27 100644
--- a/drivers/bluetooth/btintel_pcie.h
+++ b/drivers/bluetooth/btintel_pcie.h
@@ -53,6 +53,7 @@
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED	(BIT(14))
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_MAC_ACCESS_ON	(BIT(16))
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_ALIVE		(BIT(23))
+/* Reflects live D-state. Updated by hardware on every D-state transition. */
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY	(BIT(24))
 
 /* Registers for MSI-X */
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-03 14:29 ` [PATCH v3] " Vladimir V. Kondratyev
@ 2026-09-03 14:36   ` Paul Menzel
  2026-09-03 14:47   ` [v3] " bluez.test.bot
  1 sibling, 0 replies; 19+ messages in thread
From: Paul Menzel @ 2026-09-03 14:36 UTC (permalink / raw)
  To: Vladimir V. Kondratyev
  Cc: marcel, luiz.dentz, chandrashekar.devegowda, arnd, kiran.k,
	linux-bluetooth, linux-kernel, lsa.uz

Dear Vladimir,


Thank you for the third patch iteration.

Am 03.09.26 um 16:29 schrieb Vladimir V. Kondratyev:
> btintel_pcie returns -16 (EBUSY) during suspend, causing the entire suspend
> operation to abort on Intel Lunar Lake hardware. The system immediately resumes
> after every suspend attempt:
>    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
> 
> btintel_pcie_set_dxstate() falls back to checking the controller state via
> btintel_pcie_in_d3/d0() when the alive interrupt is missed. However, these
> helpers read boot_stage_cache, which is only updated by the interrupt
> handler. As such, if the interrupt was missed, the cache is stale and the
> fallback check always fails, exhausting all retries and returning -EBUSY,
> causing suspend to abort.
> 
> The fix involves re-reading the hardware register before the fallback state
> check, consistent with btintel_pcie_resume().
> 
> Fixes: e57362f4911b ("Bluetooth: btintel_pcie: Add support for _suspend() / _resume()")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=221481
> Link: https://lore.kernel.org/linux-bluetooth/20260830151550.44687-1-lsa.uz@pm.me/
> Signed-off-by: Vladimir V. Kondratyev <vladimirkondratyev2@gmail.com>
> Tested-by: Sergey Lebedev <lsa.uz@pm.me>
> ---
>   drivers/bluetooth/btintel_pcie.c | 8 +++++---
>   drivers/bluetooth/btintel_pcie.h | 1 +
>   2 files changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
> index fda474406003..e13631e94214 100644
> --- a/drivers/bluetooth/btintel_pcie.c
> +++ b/drivers/bluetooth/btintel_pcie.c
> @@ -2777,10 +2777,12 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
>   					  BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES,
>   					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
>   
> -		/* A hardware bug may cause the alive interrupt to be missed.
> -		 * Check if the controller reached the expected state and retry
> -		 * the operation only if it hasn't.
> +		/* A hardware bug may cause the alive interrupt to be missed. Refresh
> +		 * boot_stage_cache from hardware, since only the interrupt handler
> +		 * updates it. Finally retry only if the state check still fails.
>   		 */
> +		data->boot_stage_cache = btintel_pcie_rd_reg32(data,
> +							       BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
>   		if (dxstate == BTINTEL_PCIE_STATE_D0) {
>   			if (btintel_pcie_in_d0(data))
>   				return 0;
> diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h
> index 2db85f71b2f8..f287d1ff8e27 100644
> --- a/drivers/bluetooth/btintel_pcie.h
> +++ b/drivers/bluetooth/btintel_pcie.h
> @@ -53,6 +53,7 @@
>   #define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED	(BIT(14))
>   #define BTINTEL_PCIE_CSR_BOOT_STAGE_MAC_ACCESS_ON	(BIT(16))
>   #define BTINTEL_PCIE_CSR_BOOT_STAGE_ALIVE		(BIT(23))
> +/* Reflects live D-state. Updated by hardware on every D-state transition. */
>   #define BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY	(BIT(24))
>   
>   /* Registers for MSI-X */

Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>


Kind regards,

Paul


^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-03 14:29 ` [PATCH v3] " Vladimir V. Kondratyev
  2026-09-03 14:36   ` Paul Menzel
@ 2026-09-03 14:47   ` bluez.test.bot
  1 sibling, 0 replies; 19+ messages in thread
From: bluez.test.bot @ 2026-09-03 14:47 UTC (permalink / raw)
  To: linux-bluetooth, vladimirkondratyev2

[-- Attachment #1: Type: text/plain, Size: 565 bytes --]

This is an automated email and please do not reply to this email.

Dear Submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.

----- Output -----

error: patch failed: drivers/bluetooth/btintel_pcie.h:53
error: drivers/bluetooth/btintel_pcie.h: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch

Please resolve the issue and submit the patches again.


---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-05-07 20:34 [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check Vladimir V. Kondratyev
                   ` (2 preceding siblings ...)
  2026-09-03 14:29 ` [PATCH v3] " Vladimir V. Kondratyev
@ 2026-09-03 15:35 ` Vladimir V. Kondratyev
  2026-09-03 17:20   ` Sergey Lebedev
  2026-09-03 18:40   ` [v3] " bluez.test.bot
  2026-09-03 19:22 ` [PATCH v4] " Vladimir V. Kondratyev
  4 siblings, 2 replies; 19+ messages in thread
From: Vladimir V. Kondratyev @ 2026-09-03 15:35 UTC (permalink / raw)
  To: marcel, luiz.dentz, pmenzel, chandrashekar.devegowda, arnd,
	kiran.k, linux-bluetooth, linux-kernel, lsa.uz
  Cc: Vladimir V. Kondratyev

btintel_pcie returns -16 (EBUSY) during suspend, causing the entire suspend
operation to abort on Intel Lunar Lake hardware. The system immediately resumes
after every suspend attempt:
  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

btintel_pcie_set_dxstate() falls back to checking the controller state via
btintel_pcie_in_d3/d0() when the alive interrupt is missed. However, these
helpers read boot_stage_cache, which is only updated by the interrupt
handler. As such, if the interrupt was missed, the cache is stale and the
fallback check always fails, exhausting all retries and returning -EBUSY,
causing suspend to abort.

The fix involves re-reading the hardware register before the fallback state
check, consistent with btintel_pcie_resume().

Fixes: e57362f4911b ("Bluetooth: btintel_pcie: Add support for _suspend() / _resume()")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221481
Link: https://lore.kernel.org/linux-bluetooth/20260830151550.44687-1-lsa.uz@pm.me/
Signed-off-by: Vladimir V. Kondratyev <vladimirkondratyev2@gmail.com>
Tested-by: Sergey Lebedev <lsa.uz@pm.me>
---
 drivers/bluetooth/btintel_pcie.c | 8 +++++---
 drivers/bluetooth/btintel_pcie.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 30923eaabed7..44ad31a5d7ed 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -3538,10 +3538,12 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
 					  BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES,
 					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
 
-		/* A hardware bug may cause the alive interrupt to be missed.
-		 * Check if the controller reached the expected state and retry
-		 * the operation only if it hasn't.
+		/* A hardware bug may cause the alive interrupt to be missed. Refresh
+		 * boot_stage_cache from hardware, since only the interrupt handler
+		 * updates it. Finally retry only if the state check still fails.
 		 */
+		data->boot_stage_cache = btintel_pcie_rd_reg32(data,
+							       BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
 		if (dxstate == BTINTEL_PCIE_STATE_D0) {
 			if (btintel_pcie_in_d0(data))
 				return 0;
diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h
index 9baa214d9bbe..a7f4e590af5e 100644
--- a/drivers/bluetooth/btintel_pcie.h
+++ b/drivers/bluetooth/btintel_pcie.h
@@ -51,6 +51,7 @@
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED	(BIT(14))
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_MAC_ACCESS_ON	(BIT(16))
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_ALIVE		(BIT(23))
+/* Reflects live D-state. Updated by hardware on every D-state transition. */
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY	(BIT(24))
 
 #define BTINTEL_PCIE_CSR_DOORBELL_MBOX_READ_CONFIRM	(BIT(4))
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-03 15:35 ` [PATCH v3] " Vladimir V. Kondratyev
@ 2026-09-03 17:20   ` Sergey Lebedev
  2026-09-03 18:40   ` [v3] " bluez.test.bot
  1 sibling, 0 replies; 19+ messages in thread
From: Sergey Lebedev @ 2026-09-03 17:20 UTC (permalink / raw)
  To: Vladimir V . Kondratyev
  Cc: Marcel Holtmann, Luiz Augusto von Dentz, Paul Menzel,
	Chandrashekar Devegowda, Kiran K, Arnd Bergmann, linux-bluetooth,
	linux-kernel

Vladimir, Paul,

Thank you for the quick turnaround, and for putting the D-state note in the
header — it says in one line what took me a paragraph.

Two things about v3, since my Tested-by rides on it.

The tag still holds for this revision, and not only by inspection. Between
the revision I tested and v3, the only changes are the comment wording in
btintel_pcie.c and the new comment in btintel_pcie.h. Built out of tree
from the same 7.0.0 driver, both revisions produce a .text section of
21048 bytes with the same MD5, and btintel_pcie_set_dxstate disassembles
to the same 116 instructions; only debug sections differ, by 8 bytes, from
the shifted line numbers. So the object code I exercised on the hardware
is the object code v3 produces.

The CI failure in this thread is against the 14:29 posting, whose header
hunk was cut at line 53. The 15:35 resend applies cleanly to
bluetooth-next at 6696072ffe07 — checked with git apply, and it produces
the diffstat the patch declares. As of 17:15 UTC the resend has had no CI
reply, where the earlier posting had one within eighteen minutes, so it
may be worth confirming it was picked up as a new revision.

Sergey


^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-03 15:35 ` [PATCH v3] " Vladimir V. Kondratyev
  2026-09-03 17:20   ` Sergey Lebedev
@ 2026-09-03 18:40   ` bluez.test.bot
  2026-09-03 20:19     ` Paul Menzel
  1 sibling, 1 reply; 19+ messages in thread
From: bluez.test.bot @ 2026-09-03 18:40 UTC (permalink / raw)
  To: linux-bluetooth, vladimirkondratyev2

[-- Attachment #1: Type: text/plain, Size: 2635 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1157226

---Test result---

Test Summary:
CheckPatch                    FAIL      0.97 seconds
VerifyFixes                   PASS      0.13 seconds
VerifySignedoff               PASS      0.13 seconds
GitLint                       FAIL      0.34 seconds
SubjectPrefix                 PASS      0.13 seconds
BuildKernel                   PASS      26.99 seconds
CheckAllWarning               PASS      29.40 seconds
CheckSparse                   PASS      28.36 seconds
BuildKernel32                 PASS      25.69 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      474.96 seconds
IncrementalBuild              PASS      24.73 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
#113: 
operation to abort on Intel Lunar Lake hardware. The system immediately resumes

total: 0 errors, 1 warnings, 22 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14788135.patch has style problems, please review.

NOTE: Ignored message types: UNKNOWN_COMMIT_ID

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check

6: B1 Line exceeds max length (82>80): "  Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 0"
7: B1 Line exceeds max length (82>80): "  Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 1"
8: B1 Line exceeds max length (82>80): "  Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 2"
9: B1 Line exceeds max length (98>80): "  btintel_pcie 0000:00:14.7: PM: pci_pm_suspend(): btintel_pcie_suspend [btintel_pcie] returns -16"
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found


https://github.com/bluez/bluetooth-next/pull/697

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-05-07 20:34 [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check Vladimir V. Kondratyev
                   ` (3 preceding siblings ...)
  2026-09-03 15:35 ` [PATCH v3] " Vladimir V. Kondratyev
@ 2026-09-03 19:22 ` Vladimir V. Kondratyev
  2026-09-03 19:53   ` Sergey Lebedev
  2026-09-03 21:25   ` [v4] " bluez.test.bot
  4 siblings, 2 replies; 19+ messages in thread
From: Vladimir V. Kondratyev @ 2026-09-03 19:22 UTC (permalink / raw)
  To: marcel, luiz.dentz, pmenzel, chandrashekar.devegowda, arnd,
	kiran.k, linux-bluetooth, linux-kernel, lsa.uz
  Cc: Vladimir V. Kondratyev

btintel_pcie returns -16 (EBUSY) during suspend, causing the entire
suspend operation to abort on Intel Lunar Lake hardware. The system
immediately resumes
after every suspend attempt:
  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

btintel_pcie_set_dxstate() falls back to checking the controller state via
btintel_pcie_in_d3/d0() when the alive interrupt is missed. However, these
helpers read boot_stage_cache, which is only updated by the interrupt
handler. As such, if the interrupt was missed, the cache is stale and the
fallback check always fails, exhausting all retries and returning -EBUSY,
causing suspend to abort.

The fix involves re-reading the hardware register before the fallback state
check, consistent with btintel_pcie_resume().

Fixes: e57362f4911b ("Bluetooth: btintel_pcie: Add support for _suspend() / _resume()")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221481
Link: https://lore.kernel.org/linux-bluetooth/20260830151550.44687-1-lsa.uz@pm.me/
Signed-off-by: Vladimir V. Kondratyev <vladimirkondratyev2@gmail.com>
Tested-by: Sergey Lebedev <lsa.uz@pm.me>
---
 drivers/bluetooth/btintel_pcie.c | 8 +++++---
 drivers/bluetooth/btintel_pcie.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 30923eaabed7..44ad31a5d7ed 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -3538,10 +3538,12 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
 					  BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES,
 					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
 
-		/* A hardware bug may cause the alive interrupt to be missed.
-		 * Check if the controller reached the expected state and retry
-		 * the operation only if it hasn't.
+		/* A hardware bug may cause the alive interrupt to be missed. Refresh
+		 * boot_stage_cache from hardware, since only the interrupt handler
+		 * updates it. Finally retry only if the state check still fails.
 		 */
+		data->boot_stage_cache = btintel_pcie_rd_reg32(data,
+							       BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
 		if (dxstate == BTINTEL_PCIE_STATE_D0) {
 			if (btintel_pcie_in_d0(data))
 				return 0;
diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h
index 9baa214d9bbe..a7f4e590af5e 100644
--- a/drivers/bluetooth/btintel_pcie.h
+++ b/drivers/bluetooth/btintel_pcie.h
@@ -51,6 +51,7 @@
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED	(BIT(14))
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_MAC_ACCESS_ON	(BIT(16))
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_ALIVE		(BIT(23))
+/* Reflects live D-state. Updated by hardware on every D-state transition. */
 #define BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY	(BIT(24))
 
 #define BTINTEL_PCIE_CSR_DOORBELL_MBOX_READ_CONFIRM	(BIT(4))
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v4] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-03 19:22 ` [PATCH v4] " Vladimir V. Kondratyev
@ 2026-09-03 19:53   ` Sergey Lebedev
  2026-09-03 21:25   ` [v4] " bluez.test.bot
  1 sibling, 0 replies; 19+ messages in thread
From: Sergey Lebedev @ 2026-09-03 19:53 UTC (permalink / raw)
  To: Vladimir V . Kondratyev
  Cc: Marcel Holtmann, Luiz Augusto von Dentz, Paul Menzel,
	Chandrashekar Devegowda, Kiran K, Arnd Bergmann, linux-bluetooth,
	linux-kernel

Vladimir, Paul, Chandrashekar, Kiran,

Nothing here asks for a change to v4 — it is right and my Tested-by stands. This
is the measurement behind a question I put to the list on 2026-09-02 and could
not support with numbers at the time.

The question was whether BTINTEL_PCIE_CSR_BOOT_STAGE_REG should be polled for the
target D-state, with the alive interrupt demoted to an early exit, rather than the
other way round. So I timed both against the same zero — the write in
btintel_pcie_wr_sleep_cntrl() — on Surface Pro 11 (Lunar Lake), Intel BE201,
8086:a876 rev 10, kernel 7.0.0-30, s2idle. A measurement build polls the register
every 100 us and records when bit 24 reaches the target and when gp0_received
becomes true. Four suspend/resume cycles, eight transitions:

  dxstate  register (us)              interrupt (us)
  D3       1517  1027  1085  1111     1670  1171  1085  1112
  D0       1630  1521  1676  1701     1630  1646  1676  1701

The register reaches the target state in **1.0 to 1.7 ms** and is **never later
than the interrupt**. In four of the eight it is the same 100 us sample; in two
it leads by 125 and 153 us. Against that, the current path budgets 200 ms per
attempt and three attempts — up to 600 ms per transition, twice per suspend cycle.

That is the whole of my case, and its limits are worth stating plainly. One
machine, one controller, one firmware. The poll itself is PCIe traffic and could
be perturbing what it measures, though it would have to be perturbing it in the
direction that flatters the register. And a settle time is not a guarantee: an
interrupt exists partly so the driver need not assume a bound.

But if the bound holds on Intel's own hardware, polling would delete the
stale-cache class of bug rather than catch it, and POLL_INTERVAL_US is already
declared in btintel_pcie.h and unused.

I have not written that patch, because it is your subsystem and my coverage is
one machine. What I do have is the hardware, a fixture that drops the alive
interrupt on demand, and the per-hunk method already used in this thread. So if
an RFC would be useful rather than noise, I will write one and report it the same
way — measured per hunk, with the failure injected and with it disabled. If you
would rather it came from someone with the full range of controllers, that is a
perfectly good answer and I will leave it here.

Sergey


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-03 18:40   ` [v3] " bluez.test.bot
@ 2026-09-03 20:19     ` Paul Menzel
  0 siblings, 0 replies; 19+ messages in thread
From: Paul Menzel @ 2026-09-03 20:19 UTC (permalink / raw)
  To: Vladimir V. Kondratyev; +Cc: linux-bluetooth, Sergey Lebedev



Am 03.09.26 um 20:40 schrieb bluez.test.bot@gmail.com:
> This is automated email and please do not reply to this email!
> 
> Dear submitter,
> 
> Thank you for submitting the patches to the linux bluetooth mailing list.
> This is a CI test results with your patch series:
> PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1157226
> 
> ---Test result---
> 
> Test Summary:
> CheckPatch                    FAIL      0.97 seconds
> VerifyFixes                   PASS      0.13 seconds
> VerifySignedoff               PASS      0.13 seconds
> GitLint                       FAIL      0.34 seconds
> SubjectPrefix                 PASS      0.13 seconds
> BuildKernel                   PASS      26.99 seconds
> CheckAllWarning               PASS      29.40 seconds
> CheckSparse                   PASS      28.36 seconds
> BuildKernel32                 PASS      25.69 seconds
> CheckKernelLLVM               SKIP      0.00 seconds
> TestRunnerSetup               PASS      474.96 seconds
> IncrementalBuild              PASS      24.73 seconds
> 
> Details
> ##############################
> Test: CheckPatch - FAIL
> Desc: Run checkpatch.pl script
> Output:
> [v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
> WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
> #113:
> operation to abort on Intel Lunar Lake hardware. The system immediately resumes

`scripts/checkpatch.pl` ignores lines that start with the “timestamp”.

```
# Check for line lengths > 75 in commit log, warn once
                 if ($in_commit_log && !$commit_log_long_line &&
                     length($line) > 75 &&
                     !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
                                         # file delta changes
                       $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
                                         # filename then :
                       $line =~ 
/^\s*(?:Fixes:|https?:|$link_tags_search|$signature_tags)/i ||
                                         # A Fixes:, link or signature 
tag line
                       $commit_log_possible_stack_dump)) {
                         WARN("COMMIT_LOG_LONG_LINE",
                              "Prefer a maximum 75 chars per line 
(possible unwrapped commit description?)\n" . $herecurr);
                         $commit_log_long_line = 1;
                 }
```

[…]

> ##############################
> Test: GitLint - FAIL
> Desc: Run gitlint
> Output:
> [v3] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
> 
> 6: B1 Line exceeds max length (82>80): "  Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 0"
> 7: B1 Line exceeds max length (82>80): "  Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 1"
> 8: B1 Line exceeds max length (82>80): "  Bluetooth: hci0: Timeout (200 ms) on alive interrupt for D2 entry, retry count 2"
> 9: B1 Line exceeds max length (98>80): "  btintel_pcie 0000:00:14.7: PM: pci_pm_suspend(): btintel_pcie_suspend [btintel_pcie] returns -16"

I believe the configuration in the BlueZ git archive [1] is used. No 
idea, how other commits with pasted lines entered the tree.


Kind regards,

Paul


[1]: https://github.com/bluez/bluez/blob/master/.gitlint

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [v4] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check
  2026-09-03 19:22 ` [PATCH v4] " Vladimir V. Kondratyev
  2026-09-03 19:53   ` Sergey Lebedev
@ 2026-09-03 21:25   ` bluez.test.bot
  1 sibling, 0 replies; 19+ messages in thread
From: bluez.test.bot @ 2026-09-03 21:25 UTC (permalink / raw)
  To: linux-bluetooth, vladimirkondratyev2

[-- Attachment #1: Type: text/plain, Size: 1181 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1157358

---Test result---

Test Summary:
CheckPatch                    PASS      0.98 seconds
VerifyFixes                   PASS      0.14 seconds
VerifySignedoff               PASS      0.14 seconds
GitLint                       PASS      0.34 seconds
SubjectPrefix                 PASS      0.13 seconds
BuildKernel                   PASS      26.26 seconds
CheckAllWarning               PASS      28.62 seconds
CheckSparse                   PASS      27.10 seconds
BuildKernel32                 PASS      24.99 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      461.42 seconds
IncrementalBuild              PASS      24.42 seconds

Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found


https://github.com/bluez/bluetooth-next/pull/699

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2026-09-03 21:25 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-07 20:34 [PATCH] Bluetooth: btintel_pcie: fix stale cache in set_dxstate fallback check Vladimir V. Kondratyev
2026-05-07 21:06 ` bluez.test.bot
2026-09-01 20:37 ` [PATCH] " Vladimir V. Kondratyev
2026-09-01 22:36   ` bluez.test.bot
2026-09-02  5:35   ` [PATCH] " Paul Menzel
2026-09-02  7:24     ` Sergey Lebedev
2026-09-02  8:38       ` Paul Menzel
2026-09-02  9:30     ` Sergey Lebedev
2026-09-03 14:29 ` [PATCH v3] " Vladimir V. Kondratyev
2026-09-03 14:36   ` Paul Menzel
2026-09-03 14:47   ` [v3] " bluez.test.bot
2026-09-03 15:35 ` [PATCH v3] " Vladimir V. Kondratyev
2026-09-03 17:20   ` Sergey Lebedev
2026-09-03 18:40   ` [v3] " bluez.test.bot
2026-09-03 20:19     ` Paul Menzel
2026-09-03 19:22 ` [PATCH v4] " Vladimir V. Kondratyev
2026-09-03 19:53   ` Sergey Lebedev
2026-09-03 21:25   ` [v4] " bluez.test.bot
  -- strict thread matches above, loose matches on Subject: below --
2026-08-30 15:15 [PATCH] " Sergey Lebedev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox