Commit 303e967ff90a9d19ad3f8c9028ccbfa7f408fbb3

Authored by Thomas Gleixner
Committed by Linus Torvalds
1 parent 3c8aa39d7c

[PATCH] hrtimers; add state tracking

Reintroduce ktimers feature "optimized away" by the ktimers review process:
multiple hrtimer states to enable the running of hrtimers without holding the
cpu-base-lock.

(The "optimized" rbtree hack carried only 2 states worth of information and we
need 4 for high resolution timers and dynamic ticks.)

No functional changes.

Build-fixes-from: Andrew Morton <akpm@osdl.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 67 additions and 9 deletions Side-by-side Diff

include/linux/hrtimer.h
... ... @@ -40,6 +40,34 @@
40 40 HRTIMER_RESTART, /* Timer must be restarted */
41 41 };
42 42  
  43 +/*
  44 + * Bit values to track state of the timer
  45 + *
  46 + * Possible states:
  47 + *
  48 + * 0x00 inactive
  49 + * 0x01 enqueued into rbtree
  50 + * 0x02 callback function running
  51 + * 0x03 callback function running and enqueued
  52 + * (was requeued on another CPU)
  53 + *
  54 + * The "callback function running and enqueued" status is only possible on
  55 + * SMP. It happens for example when a posix timer expired and the callback
  56 + * queued a signal. Between dropping the lock which protects the posix timer
  57 + * and reacquiring the base lock of the hrtimer, another CPU can deliver the
  58 + * signal and rearm the timer. We have to preserve the callback running state,
  59 + * as otherwise the timer could be removed before the softirq code finishes the
  60 + * the handling of the timer.
  61 + *
  62 + * The HRTIMER_STATE_ENQUEUE bit is always or'ed to the current state to
  63 + * preserve the HRTIMER_STATE_CALLBACK bit in the above scenario.
  64 + *
  65 + * All state transitions are protected by cpu_base->lock.
  66 + */
  67 +#define HRTIMER_STATE_INACTIVE 0x00
  68 +#define HRTIMER_STATE_ENQUEUED 0x01
  69 +#define HRTIMER_STATE_CALLBACK 0x02
  70 +
43 71 /**
44 72 * struct hrtimer - the basic hrtimer structure
45 73 * @node: red black tree node for time ordered insertion
... ... @@ -48,6 +76,7 @@
48 76 * which the timer is based.
49 77 * @function: timer expiry callback function
50 78 * @base: pointer to the timer base (per cpu and per clock)
  79 + * @state: state information (See bit values above)
51 80 *
52 81 * The hrtimer structure must be initialized by init_hrtimer_#CLOCKTYPE()
53 82 */
... ... @@ -56,6 +85,7 @@
56 85 ktime_t expires;
57 86 enum hrtimer_restart (*function)(struct hrtimer *);
58 87 struct hrtimer_clock_base *base;
  88 + unsigned long state;
59 89 };
60 90  
61 91 /**
62 92  
... ... @@ -141,9 +171,13 @@
141 171 extern ktime_t hrtimer_get_next_event(void);
142 172 #endif
143 173  
  174 +/*
  175 + * A timer is active, when it is enqueued into the rbtree or the callback
  176 + * function is running.
  177 + */
144 178 static inline int hrtimer_active(const struct hrtimer *timer)
145 179 {
146   - return rb_parent(&timer->node) != &timer->node;
  180 + return timer->state != HRTIMER_STATE_INACTIVE;
147 181 }
148 182  
149 183 /* Forward a hrtimer so it expires after now: */
... ... @@ -150,6 +150,23 @@
150 150 }
151 151  
152 152 /*
  153 + * Helper function to check, whether the timer is on one of the queues
  154 + */
  155 +static inline int hrtimer_is_queued(struct hrtimer *timer)
  156 +{
  157 + return timer->state & HRTIMER_STATE_ENQUEUED;
  158 +}
  159 +
  160 +/*
  161 + * Helper function to check, whether the timer is running the callback
  162 + * function
  163 + */
  164 +static inline int hrtimer_callback_running(struct hrtimer *timer)
  165 +{
  166 + return timer->state & HRTIMER_STATE_CALLBACK;
  167 +}
  168 +
  169 +/*
153 170 * Functions and macros which are different for UP/SMP systems are kept in a
154 171 * single place
155 172 */
... ... @@ -390,6 +407,11 @@
390 407 */
391 408 rb_link_node(&timer->node, parent, link);
392 409 rb_insert_color(&timer->node, &base->active);
  410 + /*
  411 + * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the
  412 + * state of a possibly running callback.
  413 + */
  414 + timer->state |= HRTIMER_STATE_ENQUEUED;
393 415  
394 416 if (!base->first || timer->expires.tv64 <
395 417 rb_entry(base->first, struct hrtimer, node)->expires.tv64)
... ... @@ -402,7 +424,8 @@
402 424 * Caller must hold the base lock.
403 425 */
404 426 static void __remove_hrtimer(struct hrtimer *timer,
405   - struct hrtimer_clock_base *base)
  427 + struct hrtimer_clock_base *base,
  428 + unsigned long newstate)
406 429 {
407 430 /*
408 431 * Remove the timer from the rbtree and replace the
... ... @@ -411,7 +434,7 @@
411 434 if (base->first == &timer->node)
412 435 base->first = rb_next(&timer->node);
413 436 rb_erase(&timer->node, &base->active);
414   - rb_set_parent(&timer->node, &timer->node);
  437 + timer->state = newstate;
415 438 }
416 439  
417 440 /*
... ... @@ -420,8 +443,8 @@
420 443 static inline int
421 444 remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
422 445 {
423   - if (hrtimer_active(timer)) {
424   - __remove_hrtimer(timer, base);
  446 + if (hrtimer_is_queued(timer)) {
  447 + __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE);
425 448 return 1;
426 449 }
427 450 return 0;
... ... @@ -493,7 +516,7 @@
493 516  
494 517 base = lock_hrtimer_base(timer, &flags);
495 518  
496   - if (base->cpu_base->curr_timer != timer)
  519 + if (!hrtimer_callback_running(timer))
497 520 ret = remove_hrtimer(timer, base);
498 521  
499 522 unlock_hrtimer_base(timer, &flags);
... ... @@ -598,7 +621,6 @@
598 621 clock_id = CLOCK_MONOTONIC;
599 622  
600 623 timer->base = &cpu_base->clock_base[clock_id];
601   - rb_set_parent(&timer->node, &timer->node);
602 624 }
603 625 EXPORT_SYMBOL_GPL(hrtimer_init);
604 626  
605 627  
... ... @@ -649,13 +671,14 @@
649 671  
650 672 fn = timer->function;
651 673 set_curr_timer(cpu_base, timer);
652   - __remove_hrtimer(timer, base);
  674 + __remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK);
653 675 spin_unlock_irq(&cpu_base->lock);
654 676  
655 677 restart = fn(timer);
656 678  
657 679 spin_lock_irq(&cpu_base->lock);
658 680  
  681 + timer->state &= ~HRTIMER_STATE_CALLBACK;
659 682 if (restart != HRTIMER_NORESTART) {
660 683 BUG_ON(hrtimer_active(timer));
661 684 enqueue_hrtimer(timer, base);
... ... @@ -826,7 +849,8 @@
826 849  
827 850 while ((node = rb_first(&old_base->active))) {
828 851 timer = rb_entry(node, struct hrtimer, node);
829   - __remove_hrtimer(timer, old_base);
  852 + BUG_ON(timer->state & HRTIMER_STATE_CALLBACK);
  853 + __remove_hrtimer(timer, old_base, HRTIMER_STATE_INACTIVE);
830 854 timer->base = new_base;
831 855 enqueue_hrtimer(timer, new_base);
832 856 }