Commit 288867ec5c377db82933b64460ce050e5c998ee9

Authored by Thomas Gleixner
1 parent 593195f9b2

[hrtimer] Remove listhead from hrtimer struct

The list_head in the hrtimer structure was introduced for easy access
to the first timer with the further extensions of real high resolution
timers in mind, but it turned out in the course of development that
it is not necessary for the standard use case. Remove the list head
and access the first expiry timer by a datafield in the timer base.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Showing 2 changed files with 16 additions and 17 deletions Side-by-side Diff

include/linux/hrtimer.h
... ... @@ -49,8 +49,6 @@
49 49 * struct hrtimer - the basic hrtimer structure
50 50 *
51 51 * @node: red black tree node for time ordered insertion
52   - * @list: list head for easier access to the time ordered list,
53   - * without walking the red black tree.
54 52 * @expires: the absolute expiry time in the hrtimers internal
55 53 * representation. The time is related to the clock on
56 54 * which the timer is based.
... ... @@ -63,7 +61,6 @@
63 61 */
64 62 struct hrtimer {
65 63 struct rb_node node;
66   - struct list_head list;
67 64 ktime_t expires;
68 65 enum hrtimer_state state;
69 66 int (*function)(void *);
... ... @@ -78,7 +75,7 @@
78 75 * to a base on another cpu.
79 76 * @lock: lock protecting the base and associated timers
80 77 * @active: red black tree root node for the active timers
81   - * @pending: list of pending timers for simple time ordered access
  78 + * @first: pointer to the timer node which expires first
82 79 * @resolution: the resolution of the clock, in nanoseconds
83 80 * @get_time: function to retrieve the current time of the clock
84 81 * @curr_timer: the timer which is executing a callback right now
... ... @@ -87,7 +84,7 @@
87 84 clockid_t index;
88 85 spinlock_t lock;
89 86 struct rb_root active;
90   - struct list_head pending;
  87 + struct rb_node *first;
91 88 unsigned long resolution;
92 89 ktime_t (*get_time)(void);
93 90 struct hrtimer *curr_timer;
... ... @@ -314,7 +314,6 @@
314 314 static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
315 315 {
316 316 struct rb_node **link = &base->active.rb_node;
317   - struct list_head *prev = &base->pending;
318 317 struct rb_node *parent = NULL;
319 318 struct hrtimer *entry;
320 319  
321 320  
322 321  
323 322  
324 323  
325 324  
... ... @@ -330,23 +329,24 @@
330 329 */
331 330 if (timer->expires.tv64 < entry->expires.tv64)
332 331 link = &(*link)->rb_left;
333   - else {
  332 + else
334 333 link = &(*link)->rb_right;
335   - prev = &entry->list;
336   - }
337 334 }
338 335  
339 336 /*
340   - * Insert the timer to the rbtree and to the sorted list:
  337 + * Insert the timer to the rbtree and check whether it
  338 + * replaces the first pending timer
341 339 */
342 340 rb_link_node(&timer->node, parent, link);
343 341 rb_insert_color(&timer->node, &base->active);
344   - list_add(&timer->list, prev);
345 342  
346 343 timer->state = HRTIMER_PENDING;
  344 +
  345 + if (!base->first || timer->expires.tv64 <
  346 + rb_entry(base->first, struct hrtimer, node)->expires.tv64)
  347 + base->first = &timer->node;
347 348 }
348 349  
349   -
350 350 /*
351 351 * __remove_hrtimer - internal function to remove a timer
352 352 *
353 353  
... ... @@ -355,9 +355,11 @@
355 355 static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
356 356 {
357 357 /*
358   - * Remove the timer from the sorted list and from the rbtree:
  358 + * Remove the timer from the rbtree and replace the
  359 + * first entry pointer if necessary.
359 360 */
360   - list_del(&timer->list);
  361 + if (base->first == &timer->node)
  362 + base->first = rb_next(&timer->node);
361 363 rb_erase(&timer->node, &base->active);
362 364 }
363 365  
364 366  
365 367  
... ... @@ -529,16 +531,17 @@
529 531 static inline void run_hrtimer_queue(struct hrtimer_base *base)
530 532 {
531 533 ktime_t now = base->get_time();
  534 + struct rb_node *node;
532 535  
533 536 spin_lock_irq(&base->lock);
534 537  
535   - while (!list_empty(&base->pending)) {
  538 + while ((node = base->first)) {
536 539 struct hrtimer *timer;
537 540 int (*fn)(void *);
538 541 int restart;
539 542 void *data;
540 543  
541   - timer = list_entry(base->pending.next, struct hrtimer, list);
  544 + timer = rb_entry(node, struct hrtimer, node);
542 545 if (now.tv64 <= timer->expires.tv64)
543 546 break;
544 547  
... ... @@ -732,7 +735,6 @@
732 735  
733 736 for (i = 0; i < MAX_HRTIMER_BASES; i++) {
734 737 spin_lock_init(&base->lock);
735   - INIT_LIST_HEAD(&base->pending);
736 738 base++;
737 739 }
738 740 }