From: Jos Delbar <jos.delbar-Cru1EgDzd7c@public.gmane.org>
To: "Brown, Len" <len.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: ACPI Developers
<acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
"Moore,
Robert" <robert.moore-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: Re: Linux ACPI processor driver patch: user-definable power state limit
Date: Mon, 11 Oct 2004 23:35:19 +0200 [thread overview]
Message-ID: <200410112335.19159.jos.delbar@ugent.be> (raw)
In-Reply-To: <F7DC2337C7631D4386A2DF6E8FB22B3001A193B6-N2PTB0HCzHKkrb+BlOpmy7fspsVTdybXVpNB7YpNyf8@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2224 bytes --]
Here is a new version of the power state limit patch that applies to ACPI
20040816. I also fixed a few bugs I bumped into along the way...
in acpi_processor_get_power_info_cst()
> @@ -671,7 +696,7 @@
>
> /* The first state is always C0, which is already filled. */
> pr->power.count = 1;
> - for (i = 1; i <= count; i++) {
> + for (i = 1; i < count; i++) {
> union acpi_object *element;
> union acpi_object *obj;
> struct acpi_power_register *reg;
The count value extracted from _CST is the number of the highest C state plus
1 and is not to be confused with the meaning of the
acpi_processor_power.count member (pr->power.count) which is simply the
highest C state. An extra iteration was made creating an invalid C4 state for
my processor, visible in /proc/acpi/processor/CPU0/power.
I think the current usage of acpi_processor_power.count is misleading and
propose to either rename the member to something like "max_state", or to give
the member a new meaning as the highest C state plus 1 and rework the code to
reflect that change.
in acpi_processor_get_power_info_fadt()
> @@ -901,7 +926,7 @@
> */
>
> for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
> - memset(pr->power.states, 0, sizeof(struct
acpi_processor_cx));
> + memset(&pr->power.states[i], 0, sizeof(struct
acpi_processor_cx));
>
> if (pr->pblk) {
> pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;
The acpi_processor_power.states (pr->power.states) array was not properly
initialized.
- Jos
On Sunday 10 October 2004 18:56, you wrote:
> >Do you require a new version of the patch without the "acpi_" prefix?
>
> sure, and if you can re-send a version that applies cleanly
> to the current tree, that would be great.
>
> thanks,
> -Len
>
> ps. FYI, if patches are generated with "diff -Naur from "/usr/src/linux"
> then that is easier for me to deal with. eg.
>
> a/drivers/acpi/processor.c
> vs.
> b/drivers/acpi/processor.c
>
> also, attachments are ok.
--
Jos Delbar
jos.delbar-Cru1EgDzd7c@public.gmane.org
[-- Attachment #2: processor.c.diff --]
[-- Type: text/x-diff, Size: 6070 bytes --]
--- a/drivers/acpi/processor.c 2004-10-11 22:09:52.000000000 +0200
+++ b/drivers/acpi/processor.c 2004-10-11 22:56:06.666140905 +0200
@@ -30,6 +30,13 @@
* 4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
*/
+/*
+ * 11/10/2004; Jos Delbar <jos.delbar-Cru1EgDzd7c@public.gmane.org>
+ * Add user-definable processor power state limit (cstate_limit).
+ * Various bug fixes.
+ * Patch applies to acpi-20040816-26-stable.
+ */
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -80,6 +87,17 @@
MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
MODULE_LICENSE("GPL");
+/*
+ * The cstate_limit module parameter represents the maximum processor power state or C
+ * state to promote to. Values of 1, 2 and 3 are equivalent to the C1, C2 and C3 sleep
+ * states, respectively. A value of 0 disables processor power management altogether.
+ */
+
+static int cstate_limit = ACPI_C_STATES_MAX;
+
+module_param(cstate_limit, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(cstate_limit, "Limit the processor power state (0 = disable power management)");
+
static int acpi_processor_add (struct acpi_device *device);
static int acpi_processor_remove (struct acpi_device *device, int type);
@@ -454,6 +472,7 @@
sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
break;
+ case ACPI_STATE_C0:
default:
local_irq_enable();
return;
@@ -544,7 +563,7 @@
* C0/C1
* -----
*/
- pr->power.state = ACPI_STATE_C1;
+ pr->power.state = (cstate_limit != ACPI_STATE_C0 ? ACPI_STATE_C1 : ACPI_STATE_C0);
pr->power.default_state = ACPI_STATE_C1;
for (i = 0; i <= pr->power.count; i++) {
@@ -571,15 +590,18 @@
* TBD: Investigate policy's use of CPU utilization -vs- sleep duration.
* XXX update comment.
*/
- pr->power.states[i-1].promotion.threshold.count = 10;
- pr->power.states[i-1].promotion.threshold.ticks =
- pr->power.states[i].latency_ticks;
- pr->power.states[i-1].promotion.state = i;
-
- pr->power.states[i].demotion.threshold.count = 1;
- pr->power.states[i].demotion.threshold.ticks =
- pr->power.states[i].latency_ticks;
- pr->power.states[i].demotion.state = i-1;
+ if (cstate_limit >= ACPI_STATE_C2)
+ {
+ pr->power.states[i-1].promotion.threshold.count = 10;
+ pr->power.states[i-1].promotion.threshold.ticks =
+ pr->power.states[i].latency_ticks;
+ pr->power.states[i-1].promotion.state = i;
+
+ pr->power.states[i].demotion.threshold.count = 1;
+ pr->power.states[i].demotion.threshold.ticks =
+ pr->power.states[i].latency_ticks;
+ pr->power.states[i].demotion.state = i-1;
+ }
break;
case ACPI_STATE_C3:
@@ -593,17 +615,20 @@
*
* XXX update comment.
*/
- pr->power.states[i-1].promotion.threshold.count = 4;
- pr->power.states[i-1].promotion.threshold.ticks =
- pr->power.states[i].latency_ticks;
- pr->power.states[i-1].promotion.threshold.bm = 0x0F;
- pr->power.states[i-1].promotion.state = i;
-
- pr->power.states[i].demotion.threshold.count = 1;
- pr->power.states[i].demotion.threshold.ticks =
- pr->power.states[i].latency_ticks;
- pr->power.states[i].demotion.threshold.bm = 0x0F;
- pr->power.states[i].demotion.state = i-1;
+ if (cstate_limit >= ACPI_STATE_C3)
+ {
+ pr->power.states[i-1].promotion.threshold.count = 4;
+ pr->power.states[i-1].promotion.threshold.ticks =
+ pr->power.states[i].latency_ticks;
+ pr->power.states[i-1].promotion.threshold.bm = 0x0F;
+ pr->power.states[i-1].promotion.state = i;
+
+ pr->power.states[i].demotion.threshold.count = 1;
+ pr->power.states[i].demotion.threshold.ticks =
+ pr->power.states[i].latency_ticks;
+ pr->power.states[i].demotion.threshold.bm = 0x0F;
+ pr->power.states[i].demotion.state = i-1;
+ }
break;
default:
return_VALUE(-EINVAL);
@@ -671,7 +696,7 @@
/* The first state is always C0, which is already filled. */
pr->power.count = 1;
- for (i = 1; i <= count; i++) {
+ for (i = 1; i < count; i++) {
union acpi_object *element;
union acpi_object *obj;
struct acpi_power_register *reg;
@@ -901,7 +926,7 @@
*/
for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+ memset(&pr->power.states[i], 0, sizeof(struct acpi_processor_cx));
if (pr->pblk) {
pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;
@@ -2185,10 +2210,15 @@
goto end;
seq_printf(seq, "active state: C%d\n"
- "default state: C%d\n"
- "bus master activity: %08x\n",
+ "default state: C%d\n",
pr->power.state,
- pr->power.default_state,
+ pr->power.default_state);
+
+ if (cstate_limit < ACPI_C_STATES_MAX) seq_printf(seq,
+ "user limit: C%d\n",
+ cstate_limit);
+
+ seq_printf(seq, "bus master activity: %08x\n",
pr->power.bm_activity);
seq_puts(seq, "states:\n");
@@ -2204,6 +2234,11 @@
seq_printf(seq, "type[%d] ", pr->power.states[i].type);
+ if (i > cstate_limit) {
+ seq_puts(seq, "<disabled>\n");
+ continue;
+ }
+
if (pr->power.states[i].promotion.state)
seq_printf(seq, "promotion[C%d] ",
pr->power.states[i].promotion.state);
@@ -2727,7 +2762,7 @@
printk(KERN_INFO PREFIX "%s [%s] (supports",
acpi_device_name(device), acpi_device_bid(device));
- for (i = 1; i <= pr->power.count; i++)
+ for (i = 0; i <= cstate_limit; i++)
if (pr->power.states[i].valid)
printk(" C%d", i);
if (pr->flags.throttling)
@@ -2770,7 +2805,7 @@
}
/* Unregister the idle handler when processor #0 is removed. */
- if (pr->id == 0)
+ if ((pr->id == 0) && (pr->flags.power))
pm_idle = pm_idle_save;
acpi_processor_remove_fs(device);
@@ -2793,6 +2828,10 @@
memset(&processors, 0, sizeof(processors));
memset(&errata, 0, sizeof(errata));
+ /* Check for illegal user limits. */
+ if(cstate_limit < ACPI_STATE_C0 || cstate_limit > ACPI_C_STATES_MAX)
+ return_VALUE(-EINVAL);
+
acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
if (!acpi_processor_dir)
return_VALUE(-ENODEV);
next prev parent reply other threads:[~2004-10-11 21:35 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-10-10 16:56 Linux ACPI processor driver patch: user-definable power state limit Brown, Len
[not found] ` <F7DC2337C7631D4386A2DF6E8FB22B3001A193B6-N2PTB0HCzHKkrb+BlOpmy7fspsVTdybXVpNB7YpNyf8@public.gmane.org>
2004-10-11 21:35 ` Jos Delbar [this message]
[not found] ` <200410112335.19159.jos.delbar-Cru1EgDzd7c@public.gmane.org>
2004-10-19 17:19 ` Len Brown
2004-11-05 19:45 ` Len Brown
2004-11-05 22:54 ` Dominik Brodowski
[not found] ` <20041105225438.GA8262-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>
2004-11-05 23:11 ` Len Brown
2004-11-05 23:41 ` Dominik Brodowski
[not found] ` <20041105234120.GA20761-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>
2004-11-06 0:25 ` Len Brown
2004-11-06 0:29 ` Dominik Brodowski
[not found] ` <20041106002935.GA30467-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>
2004-11-06 0:44 ` Len Brown
2004-11-06 13:15 ` Jos Delbar
2004-11-05 23:54 ` Dominik Brodowski
[not found] ` <20041105235403.GA21880-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>
2004-11-06 0:33 ` Len Brown
2004-11-05 23:39 ` Jos Delbar
[not found] ` <200411060039.28067.jos.delbar-Cru1EgDzd7c@public.gmane.org>
2004-11-05 23:55 ` Dominik Brodowski
2004-11-05 22:58 ` Len Brown
2004-11-05 23:21 ` Jos Delbar
[not found] ` <200411060021.49794.jos.delbar-Cru1EgDzd7c@public.gmane.org>
2004-11-06 1:01 ` Len Brown
2004-11-06 2:59 ` Len Brown
[not found] <200408071959.10529.jos.delbar@ugent.be>
[not found] ` <200408071959.10529.jos.delbar-Cru1EgDzd7c@public.gmane.org>
2004-10-09 5:52 ` Len Brown
2004-10-10 14:36 ` Jos Delbar
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=200410112335.19159.jos.delbar@ugent.be \
--to=jos.delbar-cru1egdzd7c@public.gmane.org \
--cc=acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=len.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=robert.moore-ral2JQCrhuEAvxtiuMwx3w@public.gmane.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.