From: johannes.goede@oss.qualcomm.com
To: "Ali Ahmet Memiş" <aliamemis@disroot.org>,
"Rafael J . Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>, Armin Wolf <W_Armin@gmx.de>,
Charis Stratakis <c.stratakis@proton.me>,
linux-acpi@vger.kernel.org, linux-pm@vger.kernel.org,
regressions@lists.linux.dev,
Mark Pearson <mpearson-lenovo@squebb.ca>,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] ACPI: battery: Re-read battery information in the complete callback
Date: Tue, 13 Oct 2026 11:33:11 +0200 [thread overview]
Message-ID: <fb993dd3-ee56-4e3d-aa16-573f011518f1@oss.qualcomm.com> (raw)
In-Reply-To: <20261012225141.13683-1-aliamemis@disroot.org>
Hi,
On 13-Oct-26 00:46, Ali Ahmet Memiş wrote:
> Since commit d33e89d12295 ("thermal: core: Suspend thermal zones later
> and resume them earlier"), thermal zones are resumed from dpm_complete(),
> before the PM_POST_SUSPEND notifier that re-reads _BIX and _BST. On
> ThinkPad P1 Gen2 and P53, INT3403 _TMP calls \GTST which switches the EC
> page selector (HIID) without taking the BATM mutex used by the battery
> methods. ACPICA releases the interpreter lock around EC accesses
I'm wondering if this "ACPICA releases the interpreter lock around EC
accesses" is not the real problem here. Recently I've learned / heard
from a trusted source that Windows ACPI subsystem is very much single
threaded. So it is nice that ACPI has these mutexes and other stuff
to support multi-threading but as long as Windows ACPI interpreter is
not multi-threaded I think we may need to consider to copy Windows
behavior.
So maybe the EC accesses should keep the interpreter lock locked during
EC accesses.
And even go futher and maybe we need to introduce a big-acpi-lock,
which I guess the interpreter lock more or less is? And just serialize
all ACPI accesses since most ACPI tables clearly do not handle
multi-threaded access to ACPI methods well ?
Another example of multi-threaded ACPI calls causing problems is:
https://bugzilla.kernel.org/show_bug.cgi?id=221065
Regards,
Hans
> so the
> two methods interleave and _BIX often returns temperature page data
> after resume.
> > Evaluate _BIX and _BST in the complete callback, which runs before
> dpm_complete() resumes thermal zones and leave only the sysfs
> re-registration to the notifier.
>
> Fixes: d33e89d12295 ("thermal: core: Suspend thermal zones later and resume them earlier")
> Reported-by: Charis Stratakis <c.stratakis@proton.me>
> Closes: https://lore.kernel.org/all/37N_jFulf7n-Z55NfKfE71C_wVPxYvZ0xD_iRUg2fXu7TypDiF5PStQ6siSfVBih6fThg5WoPes8U5ZQpfVm_teMFcUGXFxz2DdMbfSWuws=@proton.me/
> Cc: stable@vger.kernel.org
> Signed-off-by: Ali Ahmet Memiş <aliamemis@disroot.org>
> ---
> Ran into this (report) while reading the EC firmware of my T490.
> The P1 Gen2 EC has the same single page selector.
>
> Tested on 7.3-rc7 with an SSDT that makes a thermal zone keep calling a
> copy of the P1 Gen2 \GTST after resume. _BIX was broken after 5 of 5
> resumes without the patch and 0 of 5 with it.
>
> Doing it in the resume callback also works but _BIX takes about 75 ms
> there right after resume against about 35 ms here (and by the complete
> callback all operation region providers have resumed too).
>
> drivers/acpi/battery.c | 62 ++++++++++++++++++++++++++++--------------
> 1 file changed, 42 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
> index 670853ec3a4d..34f2e78c4314 100644
> --- a/drivers/acpi/battery.c
> +++ b/drivers/acpi/battery.c
> @@ -107,6 +107,7 @@ struct acpi_battery {
> struct notifier_block pm_nb;
> struct list_head list;
> unsigned long flags;
> + bool resume_reregister;
>
> struct mutex property_lock; /* Protects properties below. */
> unsigned long update_time;
> @@ -1209,29 +1210,15 @@ static int battery_notify(struct notifier_block *nb,
> if (mode == PM_POST_SUSPEND || mode == PM_POST_HIBERNATION) {
> guard(mutex)(&battery->update_lock);
>
> - if (!acpi_battery_present(battery))
> + if (!battery->resume_reregister)
> return 0;
>
> - if (battery->bat) {
> - acpi_battery_refresh(battery);
> - } else {
> - int result;
> -
> - scoped_guard(mutex, &battery->property_lock) {
> - result = acpi_battery_get_info(battery);
> - if (result)
> - return result;
> - }
> + battery->resume_reregister = false;
>
> - result = sysfs_add_battery(battery);
> - if (result)
> - return result;
> - }
> + if (battery->bat)
> + sysfs_remove_battery(battery);
>
> - scoped_guard(mutex, &battery->property_lock) {
> - acpi_battery_init_alarm(battery);
> - acpi_battery_get_state(battery);
> - }
> + return sysfs_add_battery(battery);
> }
>
> return 0;
> @@ -1450,7 +1437,42 @@ static int acpi_battery_resume(struct device *dev)
> return 0;
> }
>
> -static DEFINE_SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
> +static void acpi_battery_complete(struct device *dev)
> +{
> + struct acpi_battery *battery = dev_get_drvdata(dev);
> +
> + if (!battery)
> + return;
> +
> + guard(mutex)(&battery->update_lock);
> +
> + if (!acpi_battery_present(battery))
> + return;
> +
> + /*
> + * Evaluate _BIX and _BST here before thermal zones are resumed, as
> + * some firmware shares the EC window with _TMP without locking.
> + */
> + guard(mutex)(&battery->property_lock);
> +
> + if (battery->bat) {
> + int power_unit = battery->power_unit;
> +
> + acpi_battery_get_info(battery);
> + if (power_unit != battery->power_unit)
> + battery->resume_reregister = true;
> + } else if (!acpi_battery_get_info(battery)) {
> + battery->resume_reregister = true;
> + }
> +
> + acpi_battery_init_alarm(battery);
> + acpi_battery_get_state(battery);
> +}
> +
> +static const struct dev_pm_ops acpi_battery_pm = {
> + SYSTEM_SLEEP_PM_OPS(NULL, acpi_battery_resume)
> + .complete = pm_sleep_ptr(acpi_battery_complete),
> +};
>
> static struct platform_driver acpi_battery_driver = {
> .probe = acpi_battery_probe,
next prev parent reply other threads:[~2026-10-13 9:33 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <37N_jFulf7n-Z55NfKfE71C_wVPxYvZ0xD_iRUg2fXu7TypDiF5PStQ6siSfVBih6fThg5WoPes8U5ZQpfVm_teMFcUGXFxz2DdMbfSWuws=@proton.me>
2026-10-12 22:46 ` Ali Ahmet Memiş
2026-10-12 22:58 ` Ali Ahmet Memiş
2026-10-13 1:40 ` Charis Stratakis
2026-10-13 5:34 ` Ali Ahmet Memiş
2026-10-13 9:33 ` johannes.goede [this message]
2026-10-13 11:58 ` Rafael J. Wysocki (Intel)
2026-10-13 12:30 ` Ali Ahmet Memiş
2026-10-13 13:12 ` Rafael J. Wysocki (Intel)
2026-10-13 13:36 ` johannes.goede
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fb993dd3-ee56-4e3d-aa16-573f011518f1@oss.qualcomm.com \
--to=johannes.goede@oss.qualcomm.com \
--cc=W_Armin@gmx.de \
--cc=aliamemis@disroot.org \
--cc=c.stratakis@proton.me \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=mpearson-lenovo@squebb.ca \
--cc=rafael@kernel.org \
--cc=regressions@lists.linux.dev \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®