aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-09-29 08:06:45 -0400
committerThomas Gleixner <tglx@linutronix.de>2008-09-29 11:09:13 -0400
commit7659e349672bb0d378ef8d7d62bae4c53d2bdd18 (patch)
treed1cf1862c214dc9eb93b46cbc3d123a465ce7b4f /kernel
parent6ef190cc92e33565accff6a320f0e7d90480bfe7 (diff)
hrtimer: migrate pending list on cpu offline
Impact: hrtimers which are on the pending list are not migrated at cpu offline and can be stale forever Add the pending list migration when CONFIG_HIGH_RES_TIMERS is enabled Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/hrtimer.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index b8e4dce80a7..580bc66ae13 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1610,10 +1610,36 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
1610 } 1610 }
1611} 1611}
1612 1612
1613#ifdef CONFIG_HIGH_RES_TIMERS
1614static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base,
1615 struct hrtimer_cpu_base *new_base)
1616{
1617 struct hrtimer *timer;
1618 int raise = 0;
1619
1620 while (!list_empty(&old_base->cb_pending)) {
1621 timer = list_entry(old_base->cb_pending.next,
1622 struct hrtimer, cb_entry);
1623
1624 __remove_hrtimer(timer, timer->base, HRTIMER_STATE_PENDING, 0);
1625 timer->base = &new_base->clock_base[timer->base->index];
1626 list_add_tail(&timer->cb_entry, &new_base->cb_pending);
1627 raise = 1;
1628 }
1629 return raise;
1630}
1631#else
1632static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base,
1633 struct hrtimer_cpu_base *new_base)
1634{
1635 return 0;
1636}
1637#endif
1638
1613static void migrate_hrtimers(int cpu) 1639static void migrate_hrtimers(int cpu)
1614{ 1640{
1615 struct hrtimer_cpu_base *old_base, *new_base; 1641 struct hrtimer_cpu_base *old_base, *new_base;
1616 int i; 1642 int i, raise = 0;
1617 1643
1618 BUG_ON(cpu_online(cpu)); 1644 BUG_ON(cpu_online(cpu));
1619 old_base = &per_cpu(hrtimer_bases, cpu); 1645 old_base = &per_cpu(hrtimer_bases, cpu);
@@ -1630,10 +1656,16 @@ static void migrate_hrtimers(int cpu)
1630 &new_base->clock_base[i]); 1656 &new_base->clock_base[i]);
1631 } 1657 }
1632 1658
1659 if (migrate_hrtimer_pending(old_base, new_base))
1660 raise = 1;
1661
1633 spin_unlock(&old_base->lock); 1662 spin_unlock(&old_base->lock);
1634 spin_unlock(&new_base->lock); 1663 spin_unlock(&new_base->lock);
1635 local_irq_enable(); 1664 local_irq_enable();
1636 put_cpu_var(hrtimer_bases); 1665 put_cpu_var(hrtimer_bases);
1666
1667 if (raise)
1668 hrtimer_raise_softirq();
1637} 1669}
1638#endif /* CONFIG_HOTPLUG_CPU */ 1670#endif /* CONFIG_HOTPLUG_CPU */
1639 1671