From: Chen Yu <yu.c.chen@intel.com>
To: linux-acpi@vger.kernel.org
Cc: Rui Wang <ruwang@redhat.com>,
linux-kernel@vger.kernel.org, Chen Yu <yu.c.chen@intel.com>,
Len Brown <lenb@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Pavel Machek <pavel@ucw.cz>,
Matthew Garrett <mjg59@srcf.ucam.org>,
Rui Zhang <rui.zhang@intel.com>,
linux-pm@vger.kernel.org
Subject: [PATCH][RFC] ACPI throttling: Save/restore tstate for each CPUs across suspend/resume
Date: Tue, 15 Nov 2016 01:44:04 +0800 [thread overview]
Message-ID: <1479145444-29269-1-git-send-email-yu.c.chen@intel.com> (raw)
This is a trial version and any comments are appreciated.
Previously a bug was reported that on certain Broadwell
platforms, after resuming from S3, the CPU is running at
an anomalously low speed, due to BIOS has enabled the
throttling across S3. The solution to this is to introduce
a quirk framework to save/restore tstate MSR register
around suspend/resume, in Commit 7a9c2dd08ead ("x86/pm:
Introduce quirk framework to save/restore extra MSR
registers around suspend/resume").
However more and more reports show that other platforms also
experienced the same issue, because some BIOSes would like to
adjust the tstate if he thinks the temperature is too high.
To deal with this situation, the Linux uses a compensation strategy
that, the thermal management leverages thermal_pm_notify() upon resume
to check if the Processors inside the thermal zone should be throttled
or not, thus tstate would be re-evaluated. Unfortunately on these bogus
platforms, none of the Processors are inside any thermal zones due
to BIOS's implementation. Thus tstate for Processors never has a
chance to be brought back to normal.
This patch tries to save/restore tstate on receiving the
PM_SUSPEND_PREPARE and PM_POST_SUSPEND, to be more specific,
the tstate is saved after thermal_pm_notify(PM_SUSPEND_PREPARE)
is called, while it's restored before thermal_pm_notify(PM_POST_SUSPEND),
in this way the thermal zone would adjust the tstate eventually and
also help adjust the tstate for Processors which do not have
thermal zone bound. Thus it does not imapct the old semantics.
Another concern is that, each CPU should take care of the
save/restore operation, thus this patch uses percpu workqueue
to achieve this.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=90041
Reported-by: Matthew Garrett <mjg59@srcf.ucam.org>
Reported-by: Kadir <kadir@colakoglu.nl>
Cc: Len Brown <lenb@kernel.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Rui Zhang <rui.zhang@intel.com>
Cc: linux-pm@vger.kernel.org
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
---
drivers/acpi/processor_throttling.c | 70 +++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d51ca1c..8ddc7d6 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -29,6 +29,7 @@
#include <linux/sched.h>
#include <linux/cpufreq.h>
#include <linux/acpi.h>
+#include <linux/suspend.h>
#include <acpi/processor.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -758,6 +759,75 @@ static int acpi_throttling_wrmsr(u64 value)
}
return ret;
}
+
+#ifdef CONFIG_PM_SLEEP
+static DEFINE_PER_CPU(u64, tstate_msr);
+
+static long tstate_pm_fn(void *data)
+{
+ u64 value;
+ bool save = *(bool *)data;
+
+ if (save) {
+ acpi_throttling_rdmsr(&value);
+ this_cpu_write(tstate_msr, value);
+ } else {
+ value = this_cpu_read(tstate_msr);
+ if (value)
+ acpi_throttling_wrmsr(value);
+ }
+ return 0;
+}
+
+static void tstate_check(unsigned long mode, bool suspend)
+{
+ int cpu;
+ bool save;
+
+ if (suspend && mode == PM_SUSPEND_PREPARE)
+ save = true;
+ else if (!suspend && mode == PM_POST_SUSPEND)
+ save = false;
+ else
+ return;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu)
+ work_on_cpu(cpu, tstate_pm_fn, &save);
+ put_online_cpus();
+}
+
+static int tstate_suspend(struct notifier_block *nb,
+ unsigned long mode, void *_unused)
+{
+ tstate_check(mode, true);
+ return 0;
+}
+
+static int tstate_resume(struct notifier_block *nb,
+ unsigned long mode, void *_unused)
+{
+ tstate_check(mode, false);
+ return 0;
+}
+
+static int __init tstate_pm_init(void)
+{
+ /*
+ * tstate_suspend should save tstate after
+ * thermal zone's update in thermal_pm_notify,
+ * vice versa tstate_resume restore tstate before
+ * thermal_pm_notify, thus the thermal framework
+ * has a chance to re-adjust tstate according to the
+ * temperature trend.
+ */
+ pm_notifier(tstate_suspend, -1);
+ pm_notifier(tstate_resume, 1);
+ return 0;
+}
+
+core_initcall(tstate_pm_init);
+#endif
#else
static int acpi_throttling_rdmsr(u64 *value)
{
--
2.7.4
next reply other threads:[~2016-11-14 17:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-14 17:44 Chen Yu [this message]
2016-11-22 23:03 ` [PATCH][RFC] ACPI throttling: Save/restore tstate for each CPUs across suspend/resume Rafael J. Wysocki
2016-11-29 1:27 ` Chen, Yu C
2016-11-29 1:50 ` Rafael J. Wysocki
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=1479145444-29269-1-git-send-email-yu.c.chen@intel.com \
--to=yu.c.chen@intel.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
--cc=pavel@ucw.cz \
--cc=rafael@kernel.org \
--cc=rui.zhang@intel.com \
--cc=ruwang@redhat.com \
/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;
as well as URLs for NNTP newsgroup(s).