diff options
Diffstat (limited to 'drivers/cpuidle/cpuidle.c')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 151971627757..71ecc7924b58 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -613,16 +613,31 @@ EXPORT_SYMBOL_GPL(cpuidle_register); #ifdef CONFIG_SMP +static void smp_callback(void *v) +{ + /* we already woke the CPU up, nothing more to do */ +} + /* * This function gets called when a part of the kernel has a new latency - * requirement. This means we need to get all processors out of their C-state, - * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that - * wakes them all right up. + * requirement. This means we need to get only those processors out of their + * C-state for which qos requirement is changed, and then recalculate a new + * suitable C-state. Just do a cross-cpu IPI; that wakes them all right up. */ static int cpuidle_latency_notify(struct notifier_block *b, unsigned long l, void *v) { - wake_up_all_idle_cpus(); + struct cpumask cpus; + + if (v) + cpumask_andnot(&cpus, v, cpu_isolated_mask); + else + cpumask_andnot(&cpus, cpu_online_mask, cpu_isolated_mask); + + preempt_disable(); + smp_call_function_many(&cpus, smp_callback, NULL, 1); + preempt_enable(); + return NOTIFY_OK; } |