From: Andi Kleen <andi@firstfloor.org>
To: lenb@kernel.org
Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
mjg@redhat.com, Andi Kleen <andi@firstfloor.org>,
Andi Kleen <ak@linux.intel.com>
Subject: [PATCH 4/5] ACPI: Do cpufreq clamping for throttling per package v2
Date: Mon, 6 Feb 2012 08:17:11 -0800 [thread overview]
Message-ID: <1328545032-21373-5-git-send-email-andi@firstfloor.org> (raw)
In-Reply-To: <1328545032-21373-1-git-send-email-andi@firstfloor.org>
On Intel CPUs the processor typically uses the highest frequency
set by any logical CPU. When the system overheats
Linux first forces the frequency to the lowest available one
to lower the temperature.
However this was done only per logical CPU, which means all
logical CPUs in a package would need to go through this before
the frequency is actually lowered.
Worse this delay actually prevents real throttling, because
the real throttle code only proceeds when the lowest frequency
is already reached.
So when a throttle event happens force the lowest frequency
for all CPUs in the package where it happened. The per CPU
state is now kept per package, not per logical CPU. An alternative
would be to do it per cpufreq unit, but since we want to bring
down the temperature of the complete chip it's better
to do it for all.
In principle it may even make sense to do it for all CPUs,
but I kept it on the package for now.
With this change the frequency is actually lowered, which
in terms also allows real throttling to proceed.
I also removed an unnecessary per cpu variable initialization.
v2: Fix package mapping
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
drivers/acpi/processor_thermal.c | 45 +++++++++++++++++++++++++++++++------
1 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 3b599ab..b149b6e 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -57,6 +57,27 @@ ACPI_MODULE_NAME("processor_thermal");
static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg);
static unsigned int acpi_thermal_cpufreq_is_init = 0;
+#define reduction_pctg(cpu) \
+ per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu))
+
+/*
+ * Emulate "per package data" using per cpu data (which should be really provided
+ * elsewhere)
+ *
+ * Note we can lose a CPU on cpu hotunplug, in this case we forget the state
+ * temporarily. Fortunately that's not a big issue here (I hope)
+ */
+static int phys_package_first_cpu(int cpu)
+{
+ int i;
+ int id = topology_physical_package_id(cpu);
+
+ for_each_online_cpu (i)
+ if (topology_physical_package_id(i) == id)
+ return i;
+ return 0;
+}
+
static int cpu_has_cpufreq(unsigned int cpu)
{
struct cpufreq_policy policy;
@@ -76,7 +97,7 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
max_freq = (
policy->cpuinfo.max_freq *
- (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20)
+ (100 - reduction_pctg(policy->cpu) * 20)
) / 100;
cpufreq_verify_within_limits(policy, 0, max_freq);
@@ -102,16 +123,28 @@ static int cpufreq_get_cur_state(unsigned int cpu)
if (!cpu_has_cpufreq(cpu))
return 0;
- return per_cpu(cpufreq_thermal_reduction_pctg, cpu);
+ return reduction_pctg(cpu);
}
static int cpufreq_set_cur_state(unsigned int cpu, int state)
{
+ int i;
+
if (!cpu_has_cpufreq(cpu))
return 0;
- per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state;
- cpufreq_update_policy(cpu);
+ reduction_pctg(cpu) = state;
+
+ /*
+ * Update all the CPUs in the same package because they all
+ * contribute to the temperature and often share the same
+ * frequency.
+ */
+ for_each_online_cpu (i) {
+ if (topology_physical_package_id(i) ==
+ topology_physical_package_id(cpu))
+ cpufreq_update_policy(i);
+ }
return 0;
}
@@ -119,10 +152,6 @@ void acpi_thermal_cpufreq_init(void)
{
int i;
- for (i = 0; i < nr_cpu_ids; i++)
- if (cpu_present(i))
- per_cpu(cpufreq_thermal_reduction_pctg, i) = 0;
-
i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER);
if (!i)
--
1.7.7
next prev parent reply other threads:[~2012-02-06 16:17 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-06 16:17 Updated throttling fix patchkit Andi Kleen
2012-02-06 16:17 ` [PATCH 1/5] ACPI: ec: Do request_region outside WARN() Andi Kleen
2012-03-22 6:08 ` Len Brown
2012-02-06 16:17 ` [PATCH 2/5] ACPI: Make ACPI interrupt threaded Andi Kleen
2012-02-06 16:17 ` Andi Kleen [this message]
2012-02-06 16:31 ` [PATCH 4/5] ACPI: Do cpufreq clamping for throttling per package v2 Matthew Garrett
2012-02-06 17:59 ` Andi Kleen
2012-02-13 23:30 ` Len Brown
2012-02-14 0:17 ` Matthew Garrett
2012-03-22 6:13 ` Len Brown
2012-03-30 10:05 ` Len Brown
2012-03-30 11:46 ` Matthew Garrett
2012-03-30 12:00 ` Len Brown
2012-02-06 16:17 ` [PATCH 5/5] Disable MCP limit exceeded messages from Intel IPS driver Andi Kleen
2012-02-07 19:45 ` Jesse Barnes
2012-03-22 6:25 ` Len Brown
[not found] ` <1328545032-21373-4-git-send-email-andi@firstfloor.org>
2012-02-06 16:27 ` [PATCH 3/5] ACPI: EC: Add a limited number of repeats after false EC interrupts Matthew Garrett
2012-02-06 18:01 ` Andi Kleen
2012-02-06 16:31 ` Updated throttling fix patchkit Matthew Garrett
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=1328545032-21373-5-git-send-email-andi@firstfloor.org \
--to=andi@firstfloor.org \
--cc=ak@linux.intel.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mjg@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).