diff options
| -rw-r--r-- | kernel/hrtimer.c | 53 | 
1 files changed, 35 insertions, 18 deletions
| diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index e2f91ecc01a8..1363c1aac158 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
| @@ -486,13 +486,14 @@ static inline int hrtimer_hres_active(void) | |||
| 486 | * next event | 486 | * next event | 
| 487 | * Called with interrupts disabled and base->lock held | 487 | * Called with interrupts disabled and base->lock held | 
| 488 | */ | 488 | */ | 
| 489 | static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base) | 489 | static void | 
| 490 | hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) | ||
| 490 | { | 491 | { | 
| 491 | int i; | 492 | int i; | 
| 492 | struct hrtimer_clock_base *base = cpu_base->clock_base; | 493 | struct hrtimer_clock_base *base = cpu_base->clock_base; | 
| 493 | ktime_t expires; | 494 | ktime_t expires, expires_next; | 
| 494 | 495 | ||
| 495 | cpu_base->expires_next.tv64 = KTIME_MAX; | 496 | expires_next.tv64 = KTIME_MAX; | 
| 496 | 497 | ||
| 497 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { | 498 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { | 
| 498 | struct hrtimer *timer; | 499 | struct hrtimer *timer; | 
| @@ -508,10 +509,15 @@ static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base) | |||
| 508 | */ | 509 | */ | 
| 509 | if (expires.tv64 < 0) | 510 | if (expires.tv64 < 0) | 
| 510 | expires.tv64 = 0; | 511 | expires.tv64 = 0; | 
| 511 | if (expires.tv64 < cpu_base->expires_next.tv64) | 512 | if (expires.tv64 < expires_next.tv64) | 
| 512 | cpu_base->expires_next = expires; | 513 | expires_next = expires; | 
| 513 | } | 514 | } | 
| 514 | 515 | ||
| 516 | if (skip_equal && expires_next.tv64 == cpu_base->expires_next.tv64) | ||
| 517 | return; | ||
| 518 | |||
| 519 | cpu_base->expires_next.tv64 = expires_next.tv64; | ||
| 520 | |||
| 515 | if (cpu_base->expires_next.tv64 != KTIME_MAX) | 521 | if (cpu_base->expires_next.tv64 != KTIME_MAX) | 
| 516 | tick_program_event(cpu_base->expires_next, 1); | 522 | tick_program_event(cpu_base->expires_next, 1); | 
| 517 | } | 523 | } | 
| @@ -594,7 +600,7 @@ static void retrigger_next_event(void *arg) | |||
| 594 | base->clock_base[CLOCK_REALTIME].offset = | 600 | base->clock_base[CLOCK_REALTIME].offset = | 
| 595 | timespec_to_ktime(realtime_offset); | 601 | timespec_to_ktime(realtime_offset); | 
| 596 | 602 | ||
| 597 | hrtimer_force_reprogram(base); | 603 | hrtimer_force_reprogram(base, 0); | 
| 598 | spin_unlock(&base->lock); | 604 | spin_unlock(&base->lock); | 
| 599 | } | 605 | } | 
| 600 | 606 | ||
| @@ -707,7 +713,8 @@ static int hrtimer_switch_to_hres(void) | |||
| 707 | static inline int hrtimer_hres_active(void) { return 0; } | 713 | static inline int hrtimer_hres_active(void) { return 0; } | 
| 708 | static inline int hrtimer_is_hres_enabled(void) { return 0; } | 714 | static inline int hrtimer_is_hres_enabled(void) { return 0; } | 
| 709 | static inline int hrtimer_switch_to_hres(void) { return 0; } | 715 | static inline int hrtimer_switch_to_hres(void) { return 0; } | 
| 710 | static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { } | 716 | static inline void | 
| 717 | hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } | ||
| 711 | static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, | 718 | static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, | 
| 712 | struct hrtimer_clock_base *base, | 719 | struct hrtimer_clock_base *base, | 
| 713 | int wakeup) | 720 | int wakeup) | 
| @@ -850,19 +857,29 @@ static void __remove_hrtimer(struct hrtimer *timer, | |||
| 850 | struct hrtimer_clock_base *base, | 857 | struct hrtimer_clock_base *base, | 
| 851 | unsigned long newstate, int reprogram) | 858 | unsigned long newstate, int reprogram) | 
| 852 | { | 859 | { | 
| 853 | if (timer->state & HRTIMER_STATE_ENQUEUED) { | 860 | if (!(timer->state & HRTIMER_STATE_ENQUEUED)) | 
| 854 | /* | 861 | goto out; | 
| 855 | * Remove the timer from the rbtree and replace the | 862 | |
| 856 | * first entry pointer if necessary. | 863 | /* | 
| 857 | */ | 864 | * Remove the timer from the rbtree and replace the first | 
| 858 | if (base->first == &timer->node) { | 865 | * entry pointer if necessary. | 
| 859 | base->first = rb_next(&timer->node); | 866 | */ | 
| 860 | /* Reprogram the clock event device. if enabled */ | 867 | if (base->first == &timer->node) { | 
| 861 | if (reprogram && hrtimer_hres_active()) | 868 | base->first = rb_next(&timer->node); | 
| 862 | hrtimer_force_reprogram(base->cpu_base); | 869 | #ifdef CONFIG_HIGH_RES_TIMERS | 
| 870 | /* Reprogram the clock event device. if enabled */ | ||
| 871 | if (reprogram && hrtimer_hres_active()) { | ||
| 872 | ktime_t expires; | ||
| 873 | |||
| 874 | expires = ktime_sub(hrtimer_get_expires(timer), | ||
| 875 | base->offset); | ||
| 876 | if (base->cpu_base->expires_next.tv64 == expires.tv64) | ||
| 877 | hrtimer_force_reprogram(base->cpu_base, 1); | ||
| 863 | } | 878 | } | 
| 864 | rb_erase(&timer->node, &base->active); | 879 | #endif | 
| 865 | } | 880 | } | 
| 881 | rb_erase(&timer->node, &base->active); | ||
| 882 | out: | ||
| 866 | timer->state = newstate; | 883 | timer->state = newstate; | 
| 867 | } | 884 | } | 
| 868 | 885 | ||
