diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/hrtimer.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index f073a2461faa..e6e8278bcb18 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -314,7 +314,6 @@ hrtimer_forward(struct hrtimer *timer, const ktime_t interval) | |||
314 | static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | 314 | static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) |
315 | { | 315 | { |
316 | struct rb_node **link = &base->active.rb_node; | 316 | struct rb_node **link = &base->active.rb_node; |
317 | struct list_head *prev = &base->pending; | ||
318 | struct rb_node *parent = NULL; | 317 | struct rb_node *parent = NULL; |
319 | struct hrtimer *entry; | 318 | struct hrtimer *entry; |
320 | 319 | ||
@@ -330,22 +329,23 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | |||
330 | */ | 329 | */ |
331 | if (timer->expires.tv64 < entry->expires.tv64) | 330 | if (timer->expires.tv64 < entry->expires.tv64) |
332 | link = &(*link)->rb_left; | 331 | link = &(*link)->rb_left; |
333 | else { | 332 | else |
334 | link = &(*link)->rb_right; | 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 | rb_link_node(&timer->node, parent, link); | 340 | rb_link_node(&timer->node, parent, link); |
343 | rb_insert_color(&timer->node, &base->active); | 341 | rb_insert_color(&timer->node, &base->active); |
344 | list_add(&timer->list, prev); | ||
345 | 342 | ||
346 | timer->state = HRTIMER_PENDING; | 343 | timer->state = HRTIMER_PENDING; |
347 | } | ||
348 | 344 | ||
345 | if (!base->first || timer->expires.tv64 < | ||
346 | rb_entry(base->first, struct hrtimer, node)->expires.tv64) | ||
347 | base->first = &timer->node; | ||
348 | } | ||
349 | 349 | ||
350 | /* | 350 | /* |
351 | * __remove_hrtimer - internal function to remove a timer | 351 | * __remove_hrtimer - internal function to remove a timer |
@@ -355,9 +355,11 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | |||
355 | static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | 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 | rb_erase(&timer->node, &base->active); | 363 | rb_erase(&timer->node, &base->active); |
362 | } | 364 | } |
363 | 365 | ||
@@ -529,16 +531,17 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | |||
529 | static inline void run_hrtimer_queue(struct hrtimer_base *base) | 531 | static inline void run_hrtimer_queue(struct hrtimer_base *base) |
530 | { | 532 | { |
531 | ktime_t now = base->get_time(); | 533 | ktime_t now = base->get_time(); |
534 | struct rb_node *node; | ||
532 | 535 | ||
533 | spin_lock_irq(&base->lock); | 536 | spin_lock_irq(&base->lock); |
534 | 537 | ||
535 | while (!list_empty(&base->pending)) { | 538 | while ((node = base->first)) { |
536 | struct hrtimer *timer; | 539 | struct hrtimer *timer; |
537 | int (*fn)(void *); | 540 | int (*fn)(void *); |
538 | int restart; | 541 | int restart; |
539 | void *data; | 542 | void *data; |
540 | 543 | ||
541 | timer = list_entry(base->pending.next, struct hrtimer, list); | 544 | timer = rb_entry(node, struct hrtimer, node); |
542 | if (now.tv64 <= timer->expires.tv64) | 545 | if (now.tv64 <= timer->expires.tv64) |
543 | break; | 546 | break; |
544 | 547 | ||
@@ -732,7 +735,6 @@ static void __devinit init_hrtimers_cpu(int cpu) | |||
732 | 735 | ||
733 | for (i = 0; i < MAX_HRTIMER_BASES; i++) { | 736 | for (i = 0; i < MAX_HRTIMER_BASES; i++) { |
734 | spin_lock_init(&base->lock); | 737 | spin_lock_init(&base->lock); |
735 | INIT_LIST_HEAD(&base->pending); | ||
736 | base++; | 738 | base++; |
737 | } | 739 | } |
738 | } | 740 | } |