Loading include/linux/hrtimer.h +3 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,9 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device); /* Exported timer functions: */ /* To be used from cpusets, only */ extern void hrtimer_quiesce_cpu(void *cpup); /* Initialize timers: */ extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode); Loading kernel/time/hrtimer.c +44 −11 Original line number Diff line number Diff line Loading @@ -1605,13 +1605,17 @@ int hrtimers_prepare_cpu(unsigned int cpu) return 0; } #ifdef CONFIG_HOTPLUG_CPU #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_CPUSETS) static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, struct hrtimer_clock_base *new_base) struct hrtimer_clock_base *new_base, bool remove_pinned) { struct hrtimer *timer; struct timerqueue_node *node; struct timerqueue_head pinned; int is_pinned; timerqueue_init_head(&pinned); while ((node = timerqueue_getnext(&old_base->active))) { timer = container_of(node, struct hrtimer, node); Loading @@ -1624,6 +1628,13 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, * under us on another CPU */ __remove_hrtimer(timer, old_base, HRTIMER_STATE_ENQUEUED, 0); is_pinned = timer->state & HRTIMER_STATE_PINNED; if (!remove_pinned && is_pinned) { timerqueue_add(&pinned, &timer->node); continue; } timer->base = new_base; /* * Enqueue the timers on the new cpu. This does not Loading @@ -1635,17 +1646,23 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, */ enqueue_hrtimer(timer, new_base); } /* Re-queue pinned timers for non-hotplug usecase */ while ((node = timerqueue_getnext(&pinned))) { timer = container_of(node, struct hrtimer, node); timerqueue_del(&pinned, &timer->node); enqueue_hrtimer(timer, old_base); } } int hrtimers_dead_cpu(unsigned int scpu) static void __migrate_hrtimers(unsigned int scpu, bool remove_pinned) { struct hrtimer_cpu_base *old_base, *new_base; unsigned long flags; int i; BUG_ON(cpu_online(scpu)); tick_cancel_sched_timer(scpu); local_irq_disable(); local_irq_save(flags); old_base = &per_cpu(hrtimer_bases, scpu); new_base = this_cpu_ptr(&hrtimer_bases); /* Loading @@ -1657,7 +1674,7 @@ int hrtimers_dead_cpu(unsigned int scpu) for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { migrate_hrtimer_list(&old_base->clock_base[i], &new_base->clock_base[i]); &new_base->clock_base[i], remove_pinned); } raw_spin_unlock(&old_base->lock); Loading @@ -1665,12 +1682,28 @@ int hrtimers_dead_cpu(unsigned int scpu) /* Check, if we got expired work to do */ __hrtimer_peek_ahead_timers(); local_irq_enable(); return 0; local_irq_restore(flags); } #endif /* CONFIG_HOTPLUG_CPU || CONFIG_CPUSETS */ #ifdef CONFIG_HOTPLUG_CPU int hrtimers_dead_cpu(unsigned int scpu) { BUG_ON(cpu_online(scpu)); tick_cancel_sched_timer(scpu); __migrate_hrtimers(scpu, true); return 0; } #endif /* CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_CPUSETS void hrtimer_quiesce_cpu(void *cpup) { __migrate_hrtimers(*(int *)cpup, false); } #endif /* CONFIG_CPUSETS */ void __init hrtimers_init(void) { hrtimers_prepare_cpu(smp_processor_id()); Loading Loading
include/linux/hrtimer.h +3 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,9 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device); /* Exported timer functions: */ /* To be used from cpusets, only */ extern void hrtimer_quiesce_cpu(void *cpup); /* Initialize timers: */ extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode); Loading
kernel/time/hrtimer.c +44 −11 Original line number Diff line number Diff line Loading @@ -1605,13 +1605,17 @@ int hrtimers_prepare_cpu(unsigned int cpu) return 0; } #ifdef CONFIG_HOTPLUG_CPU #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_CPUSETS) static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, struct hrtimer_clock_base *new_base) struct hrtimer_clock_base *new_base, bool remove_pinned) { struct hrtimer *timer; struct timerqueue_node *node; struct timerqueue_head pinned; int is_pinned; timerqueue_init_head(&pinned); while ((node = timerqueue_getnext(&old_base->active))) { timer = container_of(node, struct hrtimer, node); Loading @@ -1624,6 +1628,13 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, * under us on another CPU */ __remove_hrtimer(timer, old_base, HRTIMER_STATE_ENQUEUED, 0); is_pinned = timer->state & HRTIMER_STATE_PINNED; if (!remove_pinned && is_pinned) { timerqueue_add(&pinned, &timer->node); continue; } timer->base = new_base; /* * Enqueue the timers on the new cpu. This does not Loading @@ -1635,17 +1646,23 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, */ enqueue_hrtimer(timer, new_base); } /* Re-queue pinned timers for non-hotplug usecase */ while ((node = timerqueue_getnext(&pinned))) { timer = container_of(node, struct hrtimer, node); timerqueue_del(&pinned, &timer->node); enqueue_hrtimer(timer, old_base); } } int hrtimers_dead_cpu(unsigned int scpu) static void __migrate_hrtimers(unsigned int scpu, bool remove_pinned) { struct hrtimer_cpu_base *old_base, *new_base; unsigned long flags; int i; BUG_ON(cpu_online(scpu)); tick_cancel_sched_timer(scpu); local_irq_disable(); local_irq_save(flags); old_base = &per_cpu(hrtimer_bases, scpu); new_base = this_cpu_ptr(&hrtimer_bases); /* Loading @@ -1657,7 +1674,7 @@ int hrtimers_dead_cpu(unsigned int scpu) for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { migrate_hrtimer_list(&old_base->clock_base[i], &new_base->clock_base[i]); &new_base->clock_base[i], remove_pinned); } raw_spin_unlock(&old_base->lock); Loading @@ -1665,12 +1682,28 @@ int hrtimers_dead_cpu(unsigned int scpu) /* Check, if we got expired work to do */ __hrtimer_peek_ahead_timers(); local_irq_enable(); return 0; local_irq_restore(flags); } #endif /* CONFIG_HOTPLUG_CPU || CONFIG_CPUSETS */ #ifdef CONFIG_HOTPLUG_CPU int hrtimers_dead_cpu(unsigned int scpu) { BUG_ON(cpu_online(scpu)); tick_cancel_sched_timer(scpu); __migrate_hrtimers(scpu, true); return 0; } #endif /* CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_CPUSETS void hrtimer_quiesce_cpu(void *cpup) { __migrate_hrtimers(*(int *)cpup, false); } #endif /* CONFIG_CPUSETS */ void __init hrtimers_init(void) { hrtimers_prepare_cpu(smp_processor_id()); Loading