cpuidle C-state accounting
Hi,
I have a question about cpuidle C-state accounting in cpuidle_idle_call() as implemented in kernel v2.6.29.
I understand it is possible for the target state entering callback to return 0, if for some reason it could not enter the requested C-state as decided by the governor. In this case, shouldn't the usage count be updated conditionally to reflect the fact that the state may or may not actually have been entered ? essentially, something like this:
cpuidle_modified.c 2009-05-19 11:39:58.000000000 +0530 renamed from cpuidle.c 2009-03-24 04:42:14.000000000 +0530 +2 -1
@@ -86,7 +86,8 @@ target_state = dev->last_state; target_state->time += (unsigned long long)dev->last_residency; - target_state->usage++; + if (dev->last_residency) + target_state->usage++; /* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect)
Cheers,
surinder
Quoted 5 lines
From: [email protected] [mailto:linux-pm- [email protected]] On Behalf Of Surinder P Singh
Sent: Tuesday, May 19, 2009 11:25 AM
Quoted 8 lines
I have a question about cpuidle C-state accounting in
cpuidle_idle_call()as implemented in kernel v2.6.29.I understand it is possible for the target state entering callback to return 0, if for some reason it could not enter the requested C-state as decided by the governor. In this case, shouldn't the usage count be updated conditionally to reflect the fact that the state may or may not actually have been entered ? essentially, something like this:
If it fails state due to bus master check you can do like the reference acpi driver does. I validated the same on OMAP3 a while back.
In code I've used I don't demote other states. But there are state aborts. In those cases residency is low or 0.
Regards,
Richard W.
Quoted 1 line
In code I've used I don't demote other states. But there are state aborts. In those cases residency is low or 0.
Indeed, its the residency=0 cases that the patch I sent in my last mail attempts to fix. The idea being, not to increment target_state->usage if dev->last_residency was 0, i.e. the state (whether it was the governor recommended state or safe_state or any other state) was not entered or used.
Cheers,
surinder
P.S Richard, pls ignore my other mail with the same content. I goofed up & missed your email in my inbox and sent the reply out of context. This mail should link it back to thread.
Hi Surinder,
Quoted 7 lines · Surinder P Singh
Quoted 1 line
In code I've used I don't demote other states. But there are state aborts. In those cases residency is low or 0.
Indeed, its the residency=0 cases that the patch I sent in my last mail attempts to fix. The idea being, not to increment
target_state->usageifdev->last_residencywas 0, i.e. the state (whether it was the governor recommended state or safe_state or any other state) was not entered or used.
That being the case , perhaps it will be useful to then have an extra 'usage' stat which shows such scenarios too for analysis purpose. Patch below :
drivers/cpuidle/cpuidle.c +5 -1
@@ -57,7 +57,10 @@ static void cpuidle_idle_call(void) dev->last_residency = target_state->enter (dev, target_state); dev->last_state = target_state; target_state->time += dev->last_residency; - target_state->usage++; +if (dev->last_residency) + target_state->usage++; +else + target_state->usage_nosuccess++;/* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect)
@@ -137,6 +140,7 @@ int cpuidle_enable_device(struct cpuidle_device *dev)for (i =0 ; i < dev->state_count; i++) { dev->states[i].usage =0 ; + dev->states[i].usage_nosuccess =0 ; dev->states[i].time =0 ; } dev->last_residency =0 ;
drivers/cpuidle/sysfs.c +0 -0
@@ -226,6 +226,7 @@ static ssize_t show_state_name(struct
cpuidle_state *state, char *buf)
define_show_state_function(exit_latency) define_show_state_function(power_usage) define_show_state_function(usage)
+define_show_state_function(usage_nosuccess)
define_show_state_function(time) define_one_state_ro(name, show_state_name); define_one_state_ro(latency, show_state_exit_latency);
include/linux/cpuidle.h +1 -0
@@ -37,6 +37,7 @@ struct cpuidle_state {unsigned int target_residency;/* in US */ unsigned int usage; +unsigned int usage_nosuccess;unsigned int time;/* in US */ int (*enter) (struct cpuidle_device *dev,
Regards,
Aneesh