Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
hrtimer: Eliminate needless reprogramming of clock events device

+35 -18
+35 -18
kernel/hrtimer.c
··· 509 509 * next event 510 510 * Called with interrupts disabled and base->lock held 511 511 */ 512 - static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base) 512 + static void 513 + hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) 513 514 { 514 515 int i; 515 516 struct hrtimer_clock_base *base = cpu_base->clock_base; 516 - ktime_t expires; 517 + ktime_t expires, expires_next; 517 518 518 - cpu_base->expires_next.tv64 = KTIME_MAX; 519 + expires_next.tv64 = KTIME_MAX; 519 520 520 521 for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { 521 522 struct hrtimer *timer; ··· 532 531 */ 533 532 if (expires.tv64 < 0) 534 533 expires.tv64 = 0; 535 - if (expires.tv64 < cpu_base->expires_next.tv64) 536 - cpu_base->expires_next = expires; 534 + if (expires.tv64 < expires_next.tv64) 535 + expires_next = expires; 537 536 } 537 + 538 + if (skip_equal && expires_next.tv64 == cpu_base->expires_next.tv64) 539 + return; 540 + 541 + cpu_base->expires_next.tv64 = expires_next.tv64; 538 542 539 543 if (cpu_base->expires_next.tv64 != KTIME_MAX) 540 544 tick_program_event(cpu_base->expires_next, 1); ··· 623 617 base->clock_base[CLOCK_REALTIME].offset = 624 618 timespec_to_ktime(realtime_offset); 625 619 626 - hrtimer_force_reprogram(base); 620 + hrtimer_force_reprogram(base, 0); 627 621 spin_unlock(&base->lock); 628 622 } 629 623 ··· 736 730 static inline int hrtimer_hres_active(void) { return 0; } 737 731 static inline int hrtimer_is_hres_enabled(void) { return 0; } 738 732 static inline int hrtimer_switch_to_hres(void) { return 0; } 739 - static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { } 733 + static inline void 734 + hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } 740 735 static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, 741 736 struct hrtimer_clock_base *base, 742 737 int wakeup) ··· 880 873 struct hrtimer_clock_base *base, 881 874 unsigned long newstate, int reprogram) 882 875 { 883 - if (timer->state & HRTIMER_STATE_ENQUEUED) { 884 - /* 885 - * Remove the timer from the rbtree and replace the 886 - * first entry pointer if necessary. 887 - */ 888 - if (base->first == &timer->node) { 889 - base->first = rb_next(&timer->node); 890 - /* Reprogram the clock event device. if enabled */ 891 - if (reprogram && hrtimer_hres_active()) 892 - hrtimer_force_reprogram(base->cpu_base); 876 + if (!(timer->state & HRTIMER_STATE_ENQUEUED)) 877 + goto out; 878 + 879 + /* 880 + * Remove the timer from the rbtree and replace the first 881 + * entry pointer if necessary. 882 + */ 883 + if (base->first == &timer->node) { 884 + base->first = rb_next(&timer->node); 885 + #ifdef CONFIG_HIGH_RES_TIMERS 886 + /* Reprogram the clock event device. if enabled */ 887 + if (reprogram && hrtimer_hres_active()) { 888 + ktime_t expires; 889 + 890 + expires = ktime_sub(hrtimer_get_expires(timer), 891 + base->offset); 892 + if (base->cpu_base->expires_next.tv64 == expires.tv64) 893 + hrtimer_force_reprogram(base->cpu_base, 1); 893 894 } 894 - rb_erase(&timer->node, &base->active); 895 + #endif 895 896 } 897 + rb_erase(&timer->node, &base->active); 898 + out: 896 899 timer->state = newstate; 897 900 } 898 901