When a PM-Qos is updated, the cpuidle driver will wakeup all the CPUs no matter what a latency is set. But actually it only need to wakeup the CPUs when a shorter latency is set. In this way we can reduce the cpu wakeup count and save battery. So we can pass the prev_value to the notifier callback and check the latency curr_value and prev_value in the cpuidle latency notifier callback. It modify a common interface(dummy --> prev_value) but shall be safe since no one use the dummy parameter currently. diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index e1f6860..1e1758c 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -498,7 +498,11 @@ static void smp_callback(void *v) static int cpuidle_latency_notify(struct notifier_block *b, unsigned long l, void *v) { - smp_call_function(smp_callback, NULL, 1); + unsigned long prev_value = (unsigned long) v; + + /* Dont't waktup processor when set a longer latency */ + if (l < prev_value) + smp_call_function(smp_callback, NULL, 1); return NOTIFY_OK; } diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 9322ff7..533b8bc 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -205,7 +205,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, if (prev_value != curr_value) { blocking_notifier_call_chain(c->notifiers, (unsigned long)curr_value, - NULL); + (void *)prev_value); return 1; } else { return 0;
Attachment:
0001-cpuidle-don-t-wakeup-processor-when-set-a-longer-lat.patch
Description: Binary data