This patch migrates all the non cpu-pinned regular and hrtimers from a particular cpu to the target cpu specified. The migration is triggered by setting the target cpu number at /sys/devices/system/cpu/cpuX/timer_migration. In the situation where the cpuX goes offline *after* the user sets X as the target_cpu, then timers are not migrated and stay on the source cpu. But this is just a short term fix and any discussion in this regard will help greatly. I have tested this patch by stressing the system using a script which continuously hotplug-add and removes the cpus. Signed-off-by: Arun R Bharadwaj <arun@xxxxxxxxxxxxxxxxxx> --- kernel/hrtimer.c | 6 ++++++ kernel/timer.c | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) Index: linux-2.6.27/kernel/timer.c =================================================================== --- linux-2.6.27.orig/kernel/timer.c +++ linux-2.6.27/kernel/timer.c @@ -547,7 +547,7 @@ int __mod_timer(struct timer_list *timer { struct tvec_base *base, *new_base; unsigned long flags; - int ret = 0; + int ret = 0, target_cpu; timer_stats_timer_set_start_info(timer); BUG_ON(!timer->function); @@ -562,6 +562,11 @@ int __mod_timer(struct timer_list *timer debug_timer_activate(timer); new_base = __get_cpu_var(tvec_bases); + target_cpu = __get_cpu_var(enable_timer_migration); + if (target_cpu != smp_processor_id() && !tbase_get_pinned(timer->base) + && cpu_online(target_cpu)) + new_base = per_cpu(tvec_bases, target_cpu); + if (base != new_base) { /* Index: linux-2.6.27/kernel/hrtimer.c =================================================================== --- linux-2.6.27.orig/kernel/hrtimer.c +++ linux-2.6.27/kernel/hrtimer.c @@ -206,8 +206,14 @@ switch_hrtimer_base(struct hrtimer *time { struct hrtimer_clock_base *new_base; struct hrtimer_cpu_base *new_cpu_base; + int target_cpu; new_cpu_base = &__get_cpu_var(hrtimer_bases); + target_cpu = __get_cpu_var(enable_timer_migration); + if (target_cpu != smp_processor_id() && !is_hrtimer_pinned(timer) + && cpu_online(target_cpu)) + new_cpu_base = &per_cpu(hrtimer_bases, target_cpu); + new_base = &new_cpu_base->clock_base[base->index]; if (base != new_base) { _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm