From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Stephen Berman <stephen.berman@gmx.net>,
"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Subject: [PATCH 4.9 41/43] ACPI: thermal: Do not call acpi_thermal_check() directly
Date: Mon, 8 Feb 2021 16:01:07 +0100 [thread overview]
Message-ID: <20210208145807.972785512@linuxfoundation.org> (raw)
In-Reply-To: <20210208145806.281758651@linuxfoundation.org>
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
commit 81b704d3e4674e09781d331df73d76675d5ad8cb upstream.
Calling acpi_thermal_check() from acpi_thermal_notify() directly
is problematic if _TMP triggers Notify () on the thermal zone for
which it has been evaluated (which happens on some systems), because
it causes a new acpi_thermal_notify() invocation to be queued up
every time and if that takes place too often, an indefinite number of
pending work items may accumulate in kacpi_notify_wq over time.
Besides, it is not really useful to queue up a new invocation of
acpi_thermal_check() if one of them is pending already.
For these reasons, rework acpi_thermal_notify() to queue up a thermal
check instead of calling acpi_thermal_check() directly and only allow
one thermal check to be pending at a time. Moreover, only allow one
acpi_thermal_check_fn() instance at a time to run
thermal_zone_device_update() for one thermal zone and make it return
early if it sees other instances running for the same thermal zone.
While at it, fold acpi_thermal_check() into acpi_thermal_check_fn(),
as it is only called from there after the other changes made here.
[This issue appears to have been exposed by commit 6d25be5782e4
("sched/core, workqueues: Distangle worker accounting from rq
lock"), but it is unclear why it was not visible earlier.]
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208877
Reported-by: Stephen Berman <stephen.berman@gmx.net>
Diagnosed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Tested-by: Stephen Berman <stephen.berman@gmx.net>
Cc: All applicable <stable@vger.kernel.org>
[bigeasy: Backported to v4.9.y, use atomic_t instead of refcount_t]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/acpi/thermal.c | 55 +++++++++++++++++++++++++++++++++----------------
1 file changed, 38 insertions(+), 17 deletions(-)
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -188,6 +188,8 @@ struct acpi_thermal {
int tz_enabled;
int kelvin_offset;
struct work_struct thermal_check_work;
+ struct mutex thermal_check_lock;
+ atomic_t thermal_check_count;
};
/* --------------------------------------------------------------------------
@@ -513,17 +515,6 @@ static int acpi_thermal_get_trip_points(
return 0;
}
-static void acpi_thermal_check(void *data)
-{
- struct acpi_thermal *tz = data;
-
- if (!tz->tz_enabled)
- return;
-
- thermal_zone_device_update(tz->thermal_zone,
- THERMAL_EVENT_UNSPECIFIED);
-}
-
/* sys I/F for generic thermal sysfs support */
static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp)
@@ -557,6 +548,8 @@ static int thermal_get_mode(struct therm
return 0;
}
+static void acpi_thermal_check_fn(struct work_struct *work);
+
static int thermal_set_mode(struct thermal_zone_device *thermal,
enum thermal_device_mode mode)
{
@@ -582,7 +575,7 @@ static int thermal_set_mode(struct therm
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"%s kernel ACPI thermal control\n",
tz->tz_enabled ? "Enable" : "Disable"));
- acpi_thermal_check(tz);
+ acpi_thermal_check_fn(&tz->thermal_check_work);
}
return 0;
}
@@ -951,6 +944,12 @@ static void acpi_thermal_unregister_ther
Driver Interface
-------------------------------------------------------------------------- */
+static void acpi_queue_thermal_check(struct acpi_thermal *tz)
+{
+ if (!work_pending(&tz->thermal_check_work))
+ queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
+}
+
static void acpi_thermal_notify(struct acpi_device *device, u32 event)
{
struct acpi_thermal *tz = acpi_driver_data(device);
@@ -961,17 +960,17 @@ static void acpi_thermal_notify(struct a
switch (event) {
case ACPI_THERMAL_NOTIFY_TEMPERATURE:
- acpi_thermal_check(tz);
+ acpi_queue_thermal_check(tz);
break;
case ACPI_THERMAL_NOTIFY_THRESHOLDS:
acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
- acpi_thermal_check(tz);
+ acpi_queue_thermal_check(tz);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, 0);
break;
case ACPI_THERMAL_NOTIFY_DEVICES:
acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
- acpi_thermal_check(tz);
+ acpi_queue_thermal_check(tz);
acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, 0);
break;
@@ -1071,7 +1070,27 @@ static void acpi_thermal_check_fn(struct
{
struct acpi_thermal *tz = container_of(work, struct acpi_thermal,
thermal_check_work);
- acpi_thermal_check(tz);
+
+ if (!tz->tz_enabled)
+ return;
+ /*
+ * In general, it is not sufficient to check the pending bit, because
+ * subsequent instances of this function may be queued after one of them
+ * has started running (e.g. if _TMP sleeps). Avoid bailing out if just
+ * one of them is running, though, because it may have done the actual
+ * check some time ago, so allow at least one of them to block on the
+ * mutex while another one is running the update.
+ */
+ if (!atomic_add_unless(&tz->thermal_check_count, -1, 1))
+ return;
+
+ mutex_lock(&tz->thermal_check_lock);
+
+ thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED);
+
+ atomic_inc(&tz->thermal_check_count);
+
+ mutex_unlock(&tz->thermal_check_lock);
}
static int acpi_thermal_add(struct acpi_device *device)
@@ -1103,6 +1122,8 @@ static int acpi_thermal_add(struct acpi_
if (result)
goto free_memory;
+ atomic_set(&tz->thermal_check_count, 3);
+ mutex_init(&tz->thermal_check_lock);
INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn);
pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device),
@@ -1168,7 +1189,7 @@ static int acpi_thermal_resume(struct de
tz->state.active |= tz->trips.active[i].flags.enabled;
}
- queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
+ acpi_queue_thermal_check(tz);
return AE_OK;
}
next prev parent reply other threads:[~2021-02-08 15:52 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-08 15:00 [PATCH 4.9 00/43] 4.9.257-rc1 review Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 01/43] net: dsa: bcm_sf2: put device node before return Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 02/43] ibmvnic: Ensure that CRQ entry read are correctly ordered Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 03/43] net_sched: reject silly cell_log in qdisc_get_rtab() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 04/43] futex,rt_mutex: Provide futex specific rt_mutex API Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 05/43] futex: Remove rt_mutex_deadlock_account_*() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 06/43] futex: Rework inconsistent rt_mutex/futex_q state Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 07/43] futex: Avoid violating the 10th rule of futex Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 08/43] futex: Replace pointless printk in fixup_owner() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 09/43] futex: Provide and use pi_state_update_owner() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 10/43] rtmutex: Remove unused argument from rt_mutex_proxy_unlock() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 11/43] futex: Use pi_state_update_owner() in put_pi_state() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 12/43] futex: Simplify fixup_pi_state_owner() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 13/43] futex: Handle faults correctly for PI futexes Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 14/43] scsi: libfc: Avoid invoking response handler twice if ep is already completed Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 15/43] mac80211: fix fast-rx encryption check Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 16/43] scsi: ibmvfc: Set default timeout to avoid crash during migration Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 17/43] objtool: Dont fail on missing symbol table Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 18/43] stable: clamp SUBLEVEL in 4.4 and 4.9 Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 19/43] USB: serial: cp210x: add pid/vid for WSDA-200-USB Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 20/43] USB: serial: cp210x: add new VID/PID for supporting Teraoka AD2000 Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 21/43] USB: serial: option: Adding support for Cinterion MV31 Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 22/43] Input: i8042 - unbreak Pegatron C15B Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 23/43] net: lapb: Copy the skb before sending a packet Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 24/43] elfcore: fix building with clang Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 25/43] USB: gadget: legacy: fix an error code in eth_bind() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 26/43] USB: usblp: dont call usb_set_interface if theres a single alt Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 27/43] usb: dwc2: Fix endpoint direction check in ep_from_windex Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 28/43] mac80211: fix station rate table updates on assoc Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 29/43] kretprobe: Avoid re-registration of the same kretprobe earlier Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 30/43] xhci: fix bounce buffer usage for non-sg list case Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 31/43] cifs: report error instead of invalid when revalidating a dentry fails Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 32/43] mmc: core: Limit retries when analyse of SDIO tuples fails Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.9 33/43] ARM: footbridge: fix dc21285 PCI configuration accessors Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 34/43] mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 35/43] mm: hugetlb: fix a race between isolating and freeing page Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 36/43] mm: hugetlb: remove VM_BUG_ON_PAGE from page_huge_active Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 37/43] mm: thp: fix MADV_REMOVE deadlock on shmem THP Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 38/43] x86/build: Disable CET instrumentation in the kernel Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 39/43] x86/apic: Add extra serialization for non-serializing MSRs Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 40/43] Input: xpad - sync supported devices with fork on GitHub Greg Kroah-Hartman
2021-02-08 15:01 ` Greg Kroah-Hartman [this message]
2021-02-08 15:01 ` [PATCH 4.9 42/43] iommu/vt-d: Do not use flush-queue when caching-mode is on Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.9 43/43] ALSA: hda/realtek - Fix typo of pincfg for Dell quirk Greg Kroah-Hartman
2021-02-08 17:28 ` [PATCH 4.9 00/43] 4.9.257-rc1 review Florian Fainelli
2021-02-08 20:43 ` Shuah Khan
2021-02-09 18:10 ` Guenter Roeck
2021-02-09 19:37 ` Naresh Kamboju
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=20210208145807.972785512@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=bigeasy@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=rafael.j.wysocki@intel.com \
--cc=stable@vger.kernel.org \
--cc=stephen.berman@gmx.net \
/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