* [PATCH 2.6] update passive cooling algorithm
@ 2004-01-11 21:12 Dominik Brodowski
2004-01-12 15:46 ` Ducrot Bruno
2004-01-28 22:43 ` Len Brown
0 siblings, 2 replies; 10+ messages in thread
From: Dominik Brodowski @ 2004-01-11 21:12 UTC (permalink / raw)
To: len.brown; +Cc: acpi-devel, cpufreq
[Len, could you test and verify this patch, and push it to Linus, please?]
The current algorithm used by Linux ACPI for passive thermal management has
two shortcomings:
- if increasing the CPU processing power as a thermal situation goes away,
throttling states are decreased later than performance states. This is
not wise -- it should be the opposite ordering of going "up".
- only if the ACPI CPUfreq driver is used, performance states are used.
A generalized approach would offer passive cooling even if the ACPI
P-States cpufreq driver cannot be used (faulty BIOS, FixedHW access, etc.)
The attached patch addresses these issues.
drivers/acpi/processor.c | 182 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 146 insertions(+), 36 deletions(-)
diff -ruN linux-original/drivers/acpi/processor.c linux/drivers/acpi/processor.c
--- linux-original/drivers/acpi/processor.c 2004-01-11 20:51:17.000000000 +0100
+++ linux/drivers/acpi/processor.c 2004-01-11 21:39:43.000000000 +0100
@@ -1091,6 +1091,113 @@
}
+#ifdef CONFIG_CPU_FREQ
+
+/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
+ * offers (in most cases) voltage scaling in addition to frequency scaling, and
+ * thus a cubic (instead of linear) reduction of energy. Also, we allow for
+ * _any_ cpufreq driver and not only the acpi-cpufreq driver.
+ */
+
+static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
+static unsigned int acpi_thermal_cpufreq_is_init = 0;
+
+
+static int cpu_has_cpufreq(unsigned int cpu)
+{
+ struct cpufreq_policy policy;
+ if (!acpi_thermal_cpufreq_is_init)
+ return -ENODEV;
+ if (!cpufreq_get_policy(&policy, cpu))
+ return -ENODEV;
+ return 0;
+}
+
+
+static int acpi_thermal_cpufreq_increase(unsigned int cpu)
+{
+ if (!cpu_has_cpufreq)
+ return -ENODEV;
+
+ if (cpufreq_thermal_reduction_pctg[cpu] < 60) {
+ cpufreq_thermal_reduction_pctg[cpu] += 20;
+ cpufreq_update_policy(cpu);
+ return 0;
+ }
+
+ return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
+{
+ if (!cpu_has_cpufreq)
+ return -ENODEV;
+
+ if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
+ cpufreq_thermal_reduction_pctg[cpu] -= 20;
+ cpufreq_update_policy(cpu);
+ return 0;
+ }
+
+ return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_notifier(
+ struct notifier_block *nb,
+ unsigned long event,
+ void *data)
+{
+ struct cpufreq_policy *policy = data;
+ unsigned long max_freq = 0;
+
+ if (event != CPUFREQ_ADJUST)
+ goto out;
+
+ max_freq = (policy->cpuinfo.max_freq * (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
+
+ cpufreq_verify_within_limits(policy, 0, max_freq);
+
+ out:
+ return 0;
+}
+
+
+static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
+ .notifier_call = acpi_thermal_cpufreq_notifier,
+};
+
+
+static void acpi_thermal_cpufreq_init(void) {
+ int i;
+
+ for (i=0; i<NR_CPUS; i++)
+ cpufreq_thermal_reduction_pctg[i] = 0;
+
+ i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+ if (!i)
+ acpi_thermal_cpufreq_is_init = 1;
+}
+
+static void acpi_thermal_cpufreq_exit(void) {
+ if (acpi_thermal_cpufreq_is_init)
+ cpufreq_unregister_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
+ acpi_thermal_cpufreq_is_init = 0;
+}
+
+#else /* ! CONFIG_CPU_FREQ */
+
+static void acpi_thermal_cpufreq_init(void) { return; }
+static void acpi_thermal_cpufreq_exit(void) { return; }
+static int acpi_thermal_cpufreq_increase(unsigned int cpu) { return -ENODEV; }
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu) { return -ENODEV; }
+
+
+#endif
+
+
int
acpi_processor_set_thermal_limit (
acpi_handle handle,
@@ -1099,7 +1206,6 @@
int result = 0;
struct acpi_processor *pr = NULL;
struct acpi_device *device = NULL;
- int px = 0;
int tx = 0;
ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
@@ -1116,12 +1222,7 @@
if (!pr)
return_VALUE(-ENODEV);
- if (!pr->flags.limit)
- return_VALUE(-ENODEV);
-
/* Thermal limits are always relative to the current Px/Tx state. */
- if (pr->flags.performance)
- pr->limit.thermal.px = pr->performance->state;
if (pr->flags.throttling)
pr->limit.thermal.tx = pr->throttling.state;
@@ -1130,26 +1231,27 @@
* performance state.
*/
- px = pr->limit.thermal.px;
tx = pr->limit.thermal.tx;
switch (type) {
case ACPI_PROCESSOR_LIMIT_NONE:
- px = 0;
+ do {
+ result = acpi_thermal_cpufreq_decrease(pr->id);
+ } while (!result);
tx = 0;
break;
case ACPI_PROCESSOR_LIMIT_INCREMENT:
- if (pr->flags.performance) {
- if (px == (pr->performance->state_count - 1))
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ /* if going up: P-states first, T-states later */
+
+ result = acpi_thermal_cpufreq_increase(pr->id);
+ if (!result)
+ goto end;
+ else if (result == -ERANGE)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"At maximum performance state\n"));
- else {
- px++;
- goto end;
- }
- }
+
if (pr->flags.throttling) {
if (tx == (pr->throttling.state_count - 1))
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -1160,37 +1262,41 @@
break;
case ACPI_PROCESSOR_LIMIT_DECREMENT:
- if (pr->flags.performance) {
- if (px == pr->performance_platform_limit)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "At minimum performance state\n"));
- else {
- px--;
- goto end;
- }
- }
+ /* if going down: T-states first, P-states later */
+
if (pr->flags.throttling) {
if (tx == 0)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"At minimum throttling state\n"));
- else
+ else {
tx--;
+ goto end;
+ }
}
+
+ result = acpi_thermal_cpufreq_decrease(pr->id);
+ if (result == -ERANGE)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "At minimum performance state\n"));
+
break;
}
end:
- pr->limit.thermal.px = px;
- pr->limit.thermal.tx = tx;
-
- result = acpi_processor_apply_limit(pr);
- if (result)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to set thermal limit\n"));
+ if (pr->flags.throttling) {
+ pr->limit.thermal.px = 0;
+ pr->limit.thermal.tx = tx;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
- pr->limit.thermal.px,
- pr->limit.thermal.tx));
+ result = acpi_processor_apply_limit(pr);
+ if (result)
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to set thermal limit\n"));
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
+ pr->limit.thermal.px,
+ pr->limit.thermal.tx));
+ } else
+ result = 0;
return_VALUE(result);
}
@@ -1813,6 +1919,8 @@
return_VALUE(-ENODEV);
}
+ acpi_thermal_cpufreq_init();
+
return_VALUE(0);
}
@@ -1822,6 +1930,8 @@
{
ACPI_FUNCTION_TRACE("acpi_processor_exit");
+ acpi_thermal_cpufreq_exit();
+
acpi_bus_unregister_driver(&acpi_processor_driver);
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 2.6] update passive cooling algorithm
2004-01-11 21:12 [PATCH 2.6] update passive cooling algorithm Dominik Brodowski
@ 2004-01-12 15:46 ` Ducrot Bruno
2004-01-12 17:39 ` Dominik Brodowski
2004-01-28 22:43 ` Len Brown
1 sibling, 1 reply; 10+ messages in thread
From: Ducrot Bruno @ 2004-01-12 15:46 UTC (permalink / raw)
To: len.brown, acpi-devel, cpufreq
On Sun, Jan 11, 2004 at 10:12:55PM +0100, Dominik Brodowski wrote:
> [Len, could you test and verify this patch, and push it to Linus, please?]
>
> The current algorithm used by Linux ACPI for passive thermal management has
> two shortcomings:
...
> +/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
> + * offers (in most cases) voltage scaling in addition to frequency scaling, and
> + * thus a cubic (instead of linear) reduction of energy. Also, we allow for
> + * _any_ cpufreq driver and not only the acpi-cpufreq driver.
> + */
Just a stupid question:
What is best if processor heat issues (apart turning on the fan)?
Reducing voltage of the processor, but still allowing it to run execution
at 100% (which is the case if the processor is heating), or reduce
amount of time allowed for the processor to execute?
--
Ducrot Bruno
-- Which is worse: ignorance or apathy?
-- Don't know. Don't care.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2.6] update passive cooling algorithm
2004-01-12 15:46 ` Ducrot Bruno
@ 2004-01-12 17:39 ` Dominik Brodowski
2004-01-12 19:11 ` Ducrot Bruno
0 siblings, 1 reply; 10+ messages in thread
From: Dominik Brodowski @ 2004-01-12 17:39 UTC (permalink / raw)
To: Ducrot Bruno; +Cc: acpi-devel, cpufreq
[-- Attachment #1.1: Type: text/plain, Size: 1218 bytes --]
On Mon, Jan 12, 2004 at 04:46:11PM +0100, Ducrot Bruno wrote:
> On Sun, Jan 11, 2004 at 10:12:55PM +0100, Dominik Brodowski wrote:
> > [Len, could you test and verify this patch, and push it to Linus, please?]
> >
> > The current algorithm used by Linux ACPI for passive thermal management has
> > two shortcomings:
>
> ...
>
> > +/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
> > + * offers (in most cases) voltage scaling in addition to frequency scaling, and
> > + * thus a cubic (instead of linear) reduction of energy. Also, we allow for
> > + * _any_ cpufreq driver and not only the acpi-cpufreq driver.
> > + */
>
> Just a stupid question:
>
> What is best if processor heat issues (apart turning on the fan)?
>
> Reducing voltage of the processor, but still allowing it to run execution
> at 100% (which is the case if the processor is heating), or reduce
> amount of time allowed for the processor to execute?
voltage scaling. It offers a much better (quadratic) saving than clock
modulation (linear saving). Doing both [and you need to do it, as the CPU
won't run with fewer volts at the same frequency] gives you cubic savings.
Dominik
[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 143 bytes --]
_______________________________________________
Cpufreq mailing list
Cpufreq@www.linux.org.uk
http://www.linux.org.uk/mailman/listinfo/cpufreq
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2.6] update passive cooling algorithm
2004-01-12 17:39 ` Dominik Brodowski
@ 2004-01-12 19:11 ` Ducrot Bruno
2004-01-13 8:40 ` Dominik Brodowski
2004-01-15 12:18 ` [ACPI] " Pavel Machek
0 siblings, 2 replies; 10+ messages in thread
From: Ducrot Bruno @ 2004-01-12 19:11 UTC (permalink / raw)
To: len.brown, acpi-devel, cpufreq
On Mon, Jan 12, 2004 at 06:39:22PM +0100, Dominik Brodowski wrote:
> On Mon, Jan 12, 2004 at 04:46:11PM +0100, Ducrot Bruno wrote:
> > On Sun, Jan 11, 2004 at 10:12:55PM +0100, Dominik Brodowski wrote:
> > > [Len, could you test and verify this patch, and push it to Linus, please?]
> > >
> > > The current algorithm used by Linux ACPI for passive thermal management has
> > > two shortcomings:
> >
> > ...
> >
> > > +/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
> > > + * offers (in most cases) voltage scaling in addition to frequency scaling, and
> > > + * thus a cubic (instead of linear) reduction of energy. Also, we allow for
> > > + * _any_ cpufreq driver and not only the acpi-cpufreq driver.
> > > + */
> >
> > Just a stupid question:
> >
> > What is best if processor heat issues (apart turning on the fan)?
> >
> > Reducing voltage of the processor, but still allowing it to run execution
> > at 100% (which is the case if the processor is heating), or reduce
> > amount of time allowed for the processor to execute?
>
> voltage scaling. It offers a much better (quadratic) saving than clock
> modulation (linear saving). Doing both [and you need to do it, as the CPU
> won't run with fewer volts at the same frequency] gives you cubic savings.
Yes I know. But does it offer more 'cooling'?
--
Ducrot Bruno
-- Which is worse: ignorance or apathy?
-- Don't know. Don't care.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2.6] update passive cooling algorithm
2004-01-12 19:11 ` Ducrot Bruno
@ 2004-01-13 8:40 ` Dominik Brodowski
2004-01-15 12:18 ` [ACPI] " Pavel Machek
1 sibling, 0 replies; 10+ messages in thread
From: Dominik Brodowski @ 2004-01-13 8:40 UTC (permalink / raw)
To: Ducrot Bruno; +Cc: acpi-devel, cpufreq
[-- Attachment #1.1: Type: text/plain, Size: 176 bytes --]
On Mon, Jan 12, 2004 at 08:11:22PM +0100, Ducrot Bruno wrote:
> Yes I know. But does it offer more 'cooling'?
energy consumption == heat generation [approximately]
Dominik
[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 143 bytes --]
_______________________________________________
Cpufreq mailing list
Cpufreq@www.linux.org.uk
http://www.linux.org.uk/mailman/listinfo/cpufreq
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [ACPI] Re: [PATCH 2.6] update passive cooling algorithm
2004-01-12 19:11 ` Ducrot Bruno
2004-01-13 8:40 ` Dominik Brodowski
@ 2004-01-15 12:18 ` Pavel Machek
2004-01-15 13:42 ` Ducrot Bruno
1 sibling, 1 reply; 10+ messages in thread
From: Pavel Machek @ 2004-01-15 12:18 UTC (permalink / raw)
To: Ducrot Bruno; +Cc: acpi-devel, cpufreq
Hi!
> > > > [Len, could you test and verify this patch, and push it to Linus, please?]
> > > >
> > > > The current algorithm used by Linux ACPI for passive thermal management has
> > > > two shortcomings:
> > >
> > > ...
> > >
> > > > +/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
> > > > + * offers (in most cases) voltage scaling in addition to frequency scaling, and
> > > > + * thus a cubic (instead of linear) reduction of energy. Also, we allow for
> > > > + * _any_ cpufreq driver and not only the acpi-cpufreq driver.
> > > > + */
> > >
> > > Just a stupid question:
> > >
> > > What is best if processor heat issues (apart turning on the fan)?
> > >
> > > Reducing voltage of the processor, but still allowing it to run execution
> > > at 100% (which is the case if the processor is heating), or reduce
> > > amount of time allowed for the processor to execute?
> >
> > voltage scaling. It offers a much better (quadratic) saving than clock
> > modulation (linear saving). Doing both [and you need to do it, as the CPU
> > won't run with fewer volts at the same frequency] gives you cubic savings.
>
> Yes I know. But does it offer more 'cooling'?
Of course.
If you eat less power, you create less heat. CPU is basically fancy
"turn-electricity-into-heat" device.
[Have you seen that "first use of PentiumPro in house appliances"
picture?]
Pavel
--
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [ACPI] Re: [PATCH 2.6] update passive cooling algorithm
2004-01-15 12:18 ` [ACPI] " Pavel Machek
@ 2004-01-15 13:42 ` Ducrot Bruno
2004-01-15 22:34 ` Pavel Machek
0 siblings, 1 reply; 10+ messages in thread
From: Ducrot Bruno @ 2004-01-15 13:42 UTC (permalink / raw)
To: Pavel Machek; +Cc: acpi-devel, cpufreq
On Thu, Jan 15, 2004 at 01:18:33PM +0100, Pavel Machek wrote:
> Hi!
>
> > > > > [Len, could you test and verify this patch, and push it to Linus, please?]
> > > > >
> > > > > The current algorithm used by Linux ACPI for passive thermal management has
> > > > > two shortcomings:
> > > >
> > > > ...
> > > >
> > > > > +/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
> > > > > + * offers (in most cases) voltage scaling in addition to frequency scaling, and
> > > > > + * thus a cubic (instead of linear) reduction of energy. Also, we allow for
> > > > > + * _any_ cpufreq driver and not only the acpi-cpufreq driver.
> > > > > + */
> > > >
> > > > Just a stupid question:
> > > >
> > > > What is best if processor heat issues (apart turning on the fan)?
> > > >
> > > > Reducing voltage of the processor, but still allowing it to run execution
> > > > at 100% (which is the case if the processor is heating), or reduce
> > > > amount of time allowed for the processor to execute?
> > >
> > > voltage scaling. It offers a much better (quadratic) saving than clock
> > > modulation (linear saving). Doing both [and you need to do it, as the CPU
> > > won't run with fewer volts at the same frequency] gives you cubic savings.
> >
> > Yes I know. But does it offer more 'cooling'?
>
> Of course.
>
> If you eat less power, you create less heat. CPU is basically fancy
> "turn-electricity-into-heat" device.
>
I don't like certitudes (I was wondering if better heat dissipation in
case of throttling even if more heat generation, but that not the case).
> [Have you seen that "first use of PentiumPro in house appliances"
> picture?]
No, but I do have seen some that have burnt in a production server,
some years ago...
--
Ducrot Bruno
-- Which is worse: ignorance or apathy?
-- Don't know. Don't care.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [ACPI] Re: [PATCH 2.6] update passive cooling algorithm
2004-01-15 13:42 ` Ducrot Bruno
@ 2004-01-15 22:34 ` Pavel Machek
2004-01-16 11:24 ` Ducrot Bruno
0 siblings, 1 reply; 10+ messages in thread
From: Pavel Machek @ 2004-01-15 22:34 UTC (permalink / raw)
To: Ducrot Bruno; +Cc: acpi-devel, cpufreq
Hi!
> > > > voltage scaling. It offers a much better (quadratic) saving than clock
> > > > modulation (linear saving). Doing both [and you need to do it, as the CPU
> > > > won't run with fewer volts at the same frequency] gives you cubic savings.
> > >
> > > Yes I know. But does it offer more 'cooling'?
> >
> > Of course.
> >
> > If you eat less power, you create less heat. CPU is basically fancy
> > "turn-electricity-into-heat" device.
> >
>
> I don't like certitudes (I was wondering if better heat dissipation
> in
Sorry.
> case of throttling even if more heat generation, but that not the
> case).
I guess throttling is way too fast (in kHz range, IIRC), so there
should not be any strange effects.
> > [Have you seen that "first use of PentiumPro in house appliances"
> > picture?]
>
> No, but I do have seen some that have burnt in a production server,
> some years ago...
There was a picture of four-plate cooker, with PPro in the middle of
each plate.
Pavel
--
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [ACPI] Re: [PATCH 2.6] update passive cooling algorithm
2004-01-15 22:34 ` Pavel Machek
@ 2004-01-16 11:24 ` Ducrot Bruno
0 siblings, 0 replies; 10+ messages in thread
From: Ducrot Bruno @ 2004-01-16 11:24 UTC (permalink / raw)
To: Pavel Machek; +Cc: acpi-devel, cpufreq
On Thu, Jan 15, 2004 at 11:34:25PM +0100, Pavel Machek wrote:
> I guess throttling is way too fast (in kHz range, IIRC), so there
> should not be any strange effects.
Agreed.
>
> > > [Have you seen that "first use of PentiumPro in house appliances"
> > > picture?]
> >
> > No, but I do have seen some that have burnt in a production server,
> > some years ago...
>
> There was a picture of four-plate cooker, with PPro in the middle of
> each plate.
Can't work, unless you like carbon..
--
Ducrot Bruno
-- Which is worse: ignorance or apathy?
-- Don't know. Don't care.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2.6] update passive cooling algorithm
2004-01-11 21:12 [PATCH 2.6] update passive cooling algorithm Dominik Brodowski
2004-01-12 15:46 ` Ducrot Bruno
@ 2004-01-28 22:43 ` Len Brown
1 sibling, 0 replies; 10+ messages in thread
From: Len Brown @ 2004-01-28 22:43 UTC (permalink / raw)
To: Dominik Brodowski; +Cc: ACPI Developers, cpufreq
Accepted into ACPI test tree
http://linux-acpi.bkbits.net/linux-acpi-test-2.6.0
http://linux-acpi.bkbits.net/linux-acpi-test-2.6.1
http://linux-acpi.bkbits.net/linux-acpi-test-2.6.2
This means it will be pulled into AKPM's mm tree on the next update.
thanks Dominik,
-Len
On Sun, 2004-01-11 at 16:12, Dominik Brodowski wrote:
> [Len, could you test and verify this patch, and push it to Linus, please?]
>
> The current algorithm used by Linux ACPI for passive thermal management has
> two shortcomings:
>
> - if increasing the CPU processing power as a thermal situation goes away,
> throttling states are decreased later than performance states. This is
> not wise -- it should be the opposite ordering of going "up".
>
> - only if the ACPI CPUfreq driver is used, performance states are used.
> A generalized approach would offer passive cooling even if the ACPI
> P-States cpufreq driver cannot be used (faulty BIOS, FixedHW access, etc.)
>
> The attached patch addresses these issues.
>
> drivers/acpi/processor.c | 182 +++++++++++++++++++++++++++++++++++++----------
> 1 files changed, 146 insertions(+), 36 deletions(-)
>
> diff -ruN linux-original/drivers/acpi/processor.c linux/drivers/acpi/processor.c
> --- linux-original/drivers/acpi/processor.c 2004-01-11 20:51:17.000000000 +0100
> +++ linux/drivers/acpi/processor.c 2004-01-11 21:39:43.000000000 +0100
> @@ -1091,6 +1091,113 @@
> }
>
>
> +#ifdef CONFIG_CPU_FREQ
> +
> +/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
> + * offers (in most cases) voltage scaling in addition to frequency scaling, and
> + * thus a cubic (instead of linear) reduction of energy. Also, we allow for
> + * _any_ cpufreq driver and not only the acpi-cpufreq driver.
> + */
> +
> +static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
> +static unsigned int acpi_thermal_cpufreq_is_init = 0;
> +
> +
> +static int cpu_has_cpufreq(unsigned int cpu)
> +{
> + struct cpufreq_policy policy;
> + if (!acpi_thermal_cpufreq_is_init)
> + return -ENODEV;
> + if (!cpufreq_get_policy(&policy, cpu))
> + return -ENODEV;
> + return 0;
> +}
> +
> +
> +static int acpi_thermal_cpufreq_increase(unsigned int cpu)
> +{
> + if (!cpu_has_cpufreq)
> + return -ENODEV;
> +
> + if (cpufreq_thermal_reduction_pctg[cpu] < 60) {
> + cpufreq_thermal_reduction_pctg[cpu] += 20;
> + cpufreq_update_policy(cpu);
> + return 0;
> + }
> +
> + return -ERANGE;
> +}
> +
> +
> +static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
> +{
> + if (!cpu_has_cpufreq)
> + return -ENODEV;
> +
> + if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
> + cpufreq_thermal_reduction_pctg[cpu] -= 20;
> + cpufreq_update_policy(cpu);
> + return 0;
> + }
> +
> + return -ERANGE;
> +}
> +
> +
> +static int acpi_thermal_cpufreq_notifier(
> + struct notifier_block *nb,
> + unsigned long event,
> + void *data)
> +{
> + struct cpufreq_policy *policy = data;
> + unsigned long max_freq = 0;
> +
> + if (event != CPUFREQ_ADJUST)
> + goto out;
> +
> + max_freq = (policy->cpuinfo.max_freq * (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
> +
> + cpufreq_verify_within_limits(policy, 0, max_freq);
> +
> + out:
> + return 0;
> +}
> +
> +
> +static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
> + .notifier_call = acpi_thermal_cpufreq_notifier,
> +};
> +
> +
> +static void acpi_thermal_cpufreq_init(void) {
> + int i;
> +
> + for (i=0; i<NR_CPUS; i++)
> + cpufreq_thermal_reduction_pctg[i] = 0;
> +
> + i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
> + if (!i)
> + acpi_thermal_cpufreq_is_init = 1;
> +}
> +
> +static void acpi_thermal_cpufreq_exit(void) {
> + if (acpi_thermal_cpufreq_is_init)
> + cpufreq_unregister_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
> +
> + acpi_thermal_cpufreq_is_init = 0;
> +}
> +
> +#else /* ! CONFIG_CPU_FREQ */
> +
> +static void acpi_thermal_cpufreq_init(void) { return; }
> +static void acpi_thermal_cpufreq_exit(void) { return; }
> +static int acpi_thermal_cpufreq_increase(unsigned int cpu) { return -ENODEV; }
> +static int acpi_thermal_cpufreq_decrease(unsigned int cpu) { return -ENODEV; }
> +
> +
> +#endif
> +
> +
> int
> acpi_processor_set_thermal_limit (
> acpi_handle handle,
> @@ -1099,7 +1206,6 @@
> int result = 0;
> struct acpi_processor *pr = NULL;
> struct acpi_device *device = NULL;
> - int px = 0;
> int tx = 0;
>
> ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
> @@ -1116,12 +1222,7 @@
> if (!pr)
> return_VALUE(-ENODEV);
>
> - if (!pr->flags.limit)
> - return_VALUE(-ENODEV);
> -
> /* Thermal limits are always relative to the current Px/Tx state. */
> - if (pr->flags.performance)
> - pr->limit.thermal.px = pr->performance->state;
> if (pr->flags.throttling)
> pr->limit.thermal.tx = pr->throttling.state;
>
> @@ -1130,26 +1231,27 @@
> * performance state.
> */
>
> - px = pr->limit.thermal.px;
> tx = pr->limit.thermal.tx;
>
> switch (type) {
>
> case ACPI_PROCESSOR_LIMIT_NONE:
> - px = 0;
> + do {
> + result = acpi_thermal_cpufreq_decrease(pr->id);
> + } while (!result);
> tx = 0;
> break;
>
> case ACPI_PROCESSOR_LIMIT_INCREMENT:
> - if (pr->flags.performance) {
> - if (px == (pr->performance->state_count - 1))
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> + /* if going up: P-states first, T-states later */
> +
> + result = acpi_thermal_cpufreq_increase(pr->id);
> + if (!result)
> + goto end;
> + else if (result == -ERANGE)
> + ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> "At maximum performance state\n"));
> - else {
> - px++;
> - goto end;
> - }
> - }
> +
> if (pr->flags.throttling) {
> if (tx == (pr->throttling.state_count - 1))
> ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> @@ -1160,37 +1262,41 @@
> break;
>
> case ACPI_PROCESSOR_LIMIT_DECREMENT:
> - if (pr->flags.performance) {
> - if (px == pr->performance_platform_limit)
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> - "At minimum performance state\n"));
> - else {
> - px--;
> - goto end;
> - }
> - }
> + /* if going down: T-states first, P-states later */
> +
> if (pr->flags.throttling) {
> if (tx == 0)
> ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> "At minimum throttling state\n"));
> - else
> + else {
> tx--;
> + goto end;
> + }
> }
> +
> + result = acpi_thermal_cpufreq_decrease(pr->id);
> + if (result == -ERANGE)
> + ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> + "At minimum performance state\n"));
> +
> break;
> }
>
> end:
> - pr->limit.thermal.px = px;
> - pr->limit.thermal.tx = tx;
> -
> - result = acpi_processor_apply_limit(pr);
> - if (result)
> - ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
> - "Unable to set thermal limit\n"));
> + if (pr->flags.throttling) {
> + pr->limit.thermal.px = 0;
> + pr->limit.thermal.tx = tx;
>
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
> - pr->limit.thermal.px,
> - pr->limit.thermal.tx));
> + result = acpi_processor_apply_limit(pr);
> + if (result)
> + ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
> + "Unable to set thermal limit\n"));
> +
> + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
> + pr->limit.thermal.px,
> + pr->limit.thermal.tx));
> + } else
> + result = 0;
>
> return_VALUE(result);
> }
> @@ -1813,6 +1919,8 @@
> return_VALUE(-ENODEV);
> }
>
> + acpi_thermal_cpufreq_init();
> +
> return_VALUE(0);
> }
>
> @@ -1822,6 +1930,8 @@
> {
> ACPI_FUNCTION_TRACE("acpi_processor_exit");
>
> + acpi_thermal_cpufreq_exit();
> +
> acpi_bus_unregister_driver(&acpi_processor_driver);
>
> remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2004-01-28 22:43 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-11 21:12 [PATCH 2.6] update passive cooling algorithm Dominik Brodowski
2004-01-12 15:46 ` Ducrot Bruno
2004-01-12 17:39 ` Dominik Brodowski
2004-01-12 19:11 ` Ducrot Bruno
2004-01-13 8:40 ` Dominik Brodowski
2004-01-15 12:18 ` [ACPI] " Pavel Machek
2004-01-15 13:42 ` Ducrot Bruno
2004-01-15 22:34 ` Pavel Machek
2004-01-16 11:24 ` Ducrot Bruno
2004-01-28 22:43 ` Len Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox