diff mbox

[1/2] ACPI processor: force throttling state when BIOS returns incorrect value

Message ID 200908171443.35622.elendil@planet.nl (mailing list archive)
State Accepted
Headers show

Commit Message

Frans Pop Aug. 17, 2009, 12:43 p.m. UTC
If the BIOS reports an invalid throttling state (which seems to be
fairly common after system boot), a reset is done to state T0.
Because of a check in acpi_processor_get_throttling_ptc(), the reset
never actually gets executed, which results in the error reoccurring
on every access of for example /proc/acpi/processor/CPU0/throttling.

Add a 'force' option to acpi_processor_set_throttling() to ensure
the reset really takes effect.

http://bugzilla.kernel.org/show_bug.cgi?id=13389

Signed-off-by: Frans Pop <elendil@planet.nl>
Acked-by: Zhang Rui <rui.zhang@intel.com>
---

This patch, together with the next one, fixes a regression introduced in
2.6.30, listed on the regression list. They have been available for 2.5
months now in bugzilla, but have not been picked up, despite various
reminders and without any reason given.

Google shows that numerous people are hitting this issue. The issue is in
itself relatively minor, but the bug in the code is clear.

The patches have been in all mu kernels and today testing has shown that
throttling works correctly with the patches applied when the system
overheats (http://bugzilla.kernel.org/show_bug.cgi?id=13918#c14).

Cheers,
FJP

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Andrew Morton Aug. 19, 2009, 6:58 p.m. UTC | #1
(cc stable)

On Mon, 17 Aug 2009 14:43:34 +0200 Frans Pop <elendil@planet.nl> wrote:

> If the BIOS reports an invalid throttling state (which seems to be
> fairly common after system boot), a reset is done to state T0.
> Because of a check in acpi_processor_get_throttling_ptc(), the reset
> never actually gets executed, which results in the error reoccurring
> on every access of for example /proc/acpi/processor/CPU0/throttling.
> 
> Add a 'force' option to acpi_processor_set_throttling() to ensure
> the reset really takes effect.
> 
> http://bugzilla.kernel.org/show_bug.cgi?id=13389
> 
> Signed-off-by: Frans Pop <elendil@planet.nl>
> Acked-by: Zhang Rui <rui.zhang@intel.com>

Unfortunately there are changes in linux-next which make this patch
inapplicable in non-trivial ways.

So we'll be needing one flavour of the patch for 2.6.30.x and 2.6.31.x
(the patch you just sent) and a different flavour for 2.6.32.

Or we preempt the pending linux-next changes and jam these patches into the
tree first.

>
> This patch, together with the next one, fixes a regression introduced in
> 2.6.30, listed on the regression list. They have been available for 2.5
> months now in bugzilla, but have not been picked up, despite various
> reminders and without any reason given.
> 
> Google shows that numerous people are hitting this issue. The issue is in
> itself relatively minor, but the bug in the code is clear.
> 
> The patches have been in all mu kernels and today testing has shown that
> throttling works correctly with the patches applied when the system
> overheats (http://bugzilla.kernel.org/show_bug.cgi?id=13918#c14).

OK, that sucks.

Guys, what happened here?  Fixing regressions surely is our number one
hair-on-fire priority, yet the ACPI developers have found other things
to be doing for two and a half months and now we have a mess on our
hands.

Did this just fall through the cracks or is there some problem?
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andrew Morton Aug. 26, 2009, 7:16 p.m. UTC | #2
On Mon, 17 Aug 2009 14:43:34 +0200
Frans Pop <elendil@planet.nl> wrote:

> --- a/drivers/acpi/processor_throttling.c
> +++ b/drivers/acpi/processor_throttling.c
> @@ -62,7 +62,8 @@ struct throttling_tstate {
>  #define THROTTLING_POSTCHANGE      (2)
>  
>  static int acpi_processor_get_throttling(struct acpi_processor *pr);
> -int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
> +int acpi_processor_set_throttling(struct acpi_processor *pr,
> +						int state, bool force);
>  

WARNING: externs should be avoided in .c files
#74: FILE: drivers/acpi/processor_throttling.c:65:
+int acpi_processor_set_throttling(struct acpi_processor *pr,

total: 0 errors, 1 warnings, 137 lines checked

checkpatch speaketh truth - there's already a declaration in
acpi/processor.h anyway.

I'll leave it alone though.  Cleaning up acpi code isn't on the agenda
for today.

Please integrate checkpatch into your patch preparation tools.  It
finds stuff.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Frans Pop Aug. 26, 2009, 7:41 p.m. UTC | #3
Thanks for picking up the patch Andrew.

On Wednesday 26 August 2009, Andrew Morton wrote:
> On Mon, 17 Aug 2009 14:43:34 +0200 Frans Pop <elendil@planet.nl> wrote:
> > --- a/drivers/acpi/processor_throttling.c
> > +++ b/drivers/acpi/processor_throttling.c
> > @@ -62,7 +62,8 @@ struct throttling_tstate {
> >  #define THROTTLING_POSTCHANGE      (2)
> >
> >  static int acpi_processor_get_throttling(struct acpi_processor *pr);
> > -int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
> > +int acpi_processor_set_throttling(struct acpi_processor *pr, 
> > +						int state, bool force);
>
> WARNING: externs should be avoided in .c files
> #74: FILE: drivers/acpi/processor_throttling.c:65:
> +int acpi_processor_set_throttling(struct acpi_processor *pr,
>
> checkpatch speaketh truth - there's already a declaration in
> acpi/processor.h anyway.
>
> I'll leave it alone though.  Cleaning up acpi code isn't on the agenda
> for today.

Yeah, but it wasn't an error introduced by my patch, so I chose to
ignore it in order to keep my change straightforward.
The whole file gives:
   total: 6 errors, 15 warnings, 1326 lines checked

I really did not want to get into that, although this is the only
error of that type. You also have to allow for my limited C skills :-/

> Please integrate checkpatch into your patch preparation tools.  It
> finds stuff.

I do run checkpatch frequently, but I don't yet have enough volume
that I have my own a toolset for preparing patches. I do have a
nice one for building kernels though, so who knows :-)

Cheers,
FJP
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Len Brown Aug. 27, 2009, 5:31 p.m. UTC | #4
> Did this just fall through the cracks

yes, during summer vacation, the cracks can sometimes be large.

Thanks for handling this one Andrew.

-Len Brown, Intel Open Source Technology Center

ps. lenb@intel.com isn't my e-mail address.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Frans Pop Aug. 27, 2009, 6:28 p.m. UTC | #5
On Thursday 27 August 2009, you wrote:
> > Did this just fall through the cracks
>
> yes, during summer vacation, the cracks can sometimes be large.

Nice to see you're back :-)

> Thanks for handling this one Andrew.
>
> -Len Brown, Intel Open Source Technology Center
>
> ps. lenb@intel.com isn't my e-mail address.

Hmmm. Then why is that address listed in bugzilla, both in the CC list for 
#13389 and in the history of that BR for both actions done by you?
That's where I took it from...

Is it simply that you need to update your bugzilla account?

Cheers,
FJP
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 39838c6..31adda1 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -66,7 +66,7 @@  static int acpi_processor_apply_limit(struct acpi_processor *pr)
 		if (pr->limit.thermal.tx > tx)
 			tx = pr->limit.thermal.tx;
 
-		result = acpi_processor_set_throttling(pr, tx);
+		result = acpi_processor_set_throttling(pr, tx, false);
 		if (result)
 			goto end;
 	}
@@ -421,12 +421,12 @@  processor_set_cur_state(struct thermal_cooling_device *cdev,
 
 	if (state <= max_pstate) {
 		if (pr->flags.throttling && pr->throttling.state)
-			result = acpi_processor_set_throttling(pr, 0);
+			result = acpi_processor_set_throttling(pr, 0, false);
 		cpufreq_set_cur_state(pr->id, state);
 	} else {
 		cpufreq_set_cur_state(pr->id, max_pstate);
 		result = acpi_processor_set_throttling(pr,
-				state - max_pstate);
+				state - max_pstate, false);
 	}
 	return result;
 }
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 2275437..841be4e 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -62,7 +62,8 @@  struct throttling_tstate {
 #define THROTTLING_POSTCHANGE      (2)
 
 static int acpi_processor_get_throttling(struct acpi_processor *pr);
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+int acpi_processor_set_throttling(struct acpi_processor *pr,
+						int state, bool force);
 
 static int acpi_processor_update_tsd_coord(void)
 {
@@ -361,7 +362,7 @@  int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
 		 */
 		target_state = throttling_limit;
 	}
-	return acpi_processor_set_throttling(pr, target_state);
+	return acpi_processor_set_throttling(pr, target_state, false);
 }
 
 /*
@@ -842,7 +843,7 @@  static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
 			ACPI_WARNING((AE_INFO,
 				"Invalid throttling state, reset"));
 			state = 0;
-			ret = acpi_processor_set_throttling(pr, state);
+			ret = acpi_processor_set_throttling(pr, state, true);
 			if (ret)
 				return ret;
 		}
@@ -915,7 +916,7 @@  static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
 }
 
 static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
-					      int state)
+					      int state, bool force)
 {
 	u32 value = 0;
 	u32 duty_mask = 0;
@@ -930,7 +931,7 @@  static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
 	if (!pr->flags.throttling)
 		return -ENODEV;
 
-	if (state == pr->throttling.state)
+	if (!force && (state == pr->throttling.state))
 		return 0;
 
 	if (state < pr->throttling_platform_limit)
@@ -988,7 +989,7 @@  static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
 }
 
 static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
-					     int state)
+					     int state, bool force)
 {
 	int ret;
 	acpi_integer value;
@@ -1002,7 +1003,7 @@  static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
 	if (!pr->flags.throttling)
 		return -ENODEV;
 
-	if (state == pr->throttling.state)
+	if (!force && (state == pr->throttling.state))
 		return 0;
 
 	if (state < pr->throttling_platform_limit)
@@ -1018,7 +1019,8 @@  static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
 	return 0;
 }
 
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
+int acpi_processor_set_throttling(struct acpi_processor *pr,
+						int state, bool force)
 {
 	cpumask_var_t saved_mask;
 	int ret = 0;
@@ -1070,7 +1072,7 @@  int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
 		/* FIXME: use work_on_cpu() */
 		set_cpus_allowed_ptr(current, cpumask_of(pr->id));
 		ret = p_throttling->acpi_processor_set_throttling(pr,
-						t_state.target_state);
+						t_state.target_state, force);
 	} else {
 		/*
 		 * When the T-state coordination is SW_ALL or HW_ALL,
@@ -1103,7 +1105,7 @@  int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
 			set_cpus_allowed_ptr(current, cpumask_of(i));
 			ret = match_pr->throttling.
 				acpi_processor_set_throttling(
-				match_pr, t_state.target_state);
+				match_pr, t_state.target_state, force);
 		}
 	}
 	/*
@@ -1201,7 +1203,7 @@  int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Disabling throttling (was T%d)\n",
 				  pr->throttling.state));
-		result = acpi_processor_set_throttling(pr, 0);
+		result = acpi_processor_set_throttling(pr, 0, false);
 		if (result)
 			goto end;
 	}
@@ -1307,7 +1309,7 @@  static ssize_t acpi_processor_write_throttling(struct file *file,
 	if (strcmp(tmpbuf, charp) != 0)
 		return -EINVAL;
 
-	result = acpi_processor_set_throttling(pr, state_val);
+	result = acpi_processor_set_throttling(pr, state_val, false);
 	if (result)
 		return result;
 
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index baf1e0a..740ac3a 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -174,7 +174,7 @@  struct acpi_processor_throttling {
 	cpumask_var_t shared_cpu_map;
 	int (*acpi_processor_get_throttling) (struct acpi_processor * pr);
 	int (*acpi_processor_set_throttling) (struct acpi_processor * pr,
-					      int state);
+					      int state, bool force);
 
 	u32 address;
 	u8 duty_offset;
@@ -321,7 +321,8 @@  static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
 /* in processor_throttling.c */
 int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
 int acpi_processor_get_throttling_info(struct acpi_processor *pr);
-extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+extern int acpi_processor_set_throttling(struct acpi_processor *pr,
+					 int state, bool force);
 extern const struct file_operations acpi_processor_throttling_fops;
 extern void acpi_processor_throttling_init(void);
 /* in processor_idle.c */