aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/hrtimer.h4
-rw-r--r--kernel/hrtimer.c12
2 files changed, 13 insertions, 3 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 6d93dce61cbb..bdd88df1b4e5 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -67,9 +67,10 @@ enum hrtimer_cb_mode {
67 * 0x02 callback function running 67 * 0x02 callback function running
68 * 0x04 callback pending (high resolution mode) 68 * 0x04 callback pending (high resolution mode)
69 * 69 *
70 * Special case: 70 * Special cases:
71 * 0x03 callback function running and enqueued 71 * 0x03 callback function running and enqueued
72 * (was requeued on another CPU) 72 * (was requeued on another CPU)
73 * 0x09 timer was migrated on CPU hotunplug
73 * The "callback function running and enqueued" status is only possible on 74 * The "callback function running and enqueued" status is only possible on
74 * SMP. It happens for example when a posix timer expired and the callback 75 * SMP. It happens for example when a posix timer expired and the callback
75 * queued a signal. Between dropping the lock which protects the posix timer 76 * queued a signal. Between dropping the lock which protects the posix timer
@@ -87,6 +88,7 @@ enum hrtimer_cb_mode {
87#define HRTIMER_STATE_ENQUEUED 0x01 88#define HRTIMER_STATE_ENQUEUED 0x01
88#define HRTIMER_STATE_CALLBACK 0x02 89#define HRTIMER_STATE_CALLBACK 0x02
89#define HRTIMER_STATE_PENDING 0x04 90#define HRTIMER_STATE_PENDING 0x04
91#define HRTIMER_STATE_MIGRATE 0x08
90 92
91/** 93/**
92 * struct hrtimer - the basic hrtimer structure 94 * struct hrtimer - the basic hrtimer structure
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index ac2f6d6d4868..ace723dd1e52 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1602,7 +1602,13 @@ static int migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
1602 timer = rb_entry(node, struct hrtimer, node); 1602 timer = rb_entry(node, struct hrtimer, node);
1603 BUG_ON(hrtimer_callback_running(timer)); 1603 BUG_ON(hrtimer_callback_running(timer));
1604 debug_hrtimer_deactivate(timer); 1604 debug_hrtimer_deactivate(timer);
1605 __remove_hrtimer(timer, old_base, HRTIMER_STATE_INACTIVE, 0); 1605
1606 /*
1607 * Mark it as STATE_MIGRATE not INACTIVE otherwise the
1608 * timer could be seen as !active and just vanish away
1609 * under us on another CPU
1610 */
1611 __remove_hrtimer(timer, old_base, HRTIMER_STATE_MIGRATE, 0);
1606 timer->base = new_base; 1612 timer->base = new_base;
1607 /* 1613 /*
1608 * Enqueue the timer. Allow reprogramming of the event device 1614 * Enqueue the timer. Allow reprogramming of the event device
@@ -1620,13 +1626,15 @@ static int migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
1620 * state, we need to do that otherwise we end up with 1626 * state, we need to do that otherwise we end up with
1621 * a stale timer. 1627 * a stale timer.
1622 */ 1628 */
1623 if (timer->state == HRTIMER_STATE_INACTIVE) { 1629 if (timer->state == HRTIMER_STATE_MIGRATE) {
1624 timer->state = HRTIMER_STATE_PENDING; 1630 timer->state = HRTIMER_STATE_PENDING;
1625 list_add_tail(&timer->cb_entry, 1631 list_add_tail(&timer->cb_entry,
1626 &new_base->cpu_base->cb_pending); 1632 &new_base->cpu_base->cb_pending);
1627 raise = 1; 1633 raise = 1;
1628 } 1634 }
1629#endif 1635#endif
1636 /* Clear the migration state bit */
1637 timer->state &= ~HRTIMER_STATE_MIGRATE;
1630 } 1638 }
1631 return raise; 1639 return raise;
1632} 1640}