Commit 6f507102 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 73964f6b 7403f41f
...@@ -509,13 +509,14 @@ static inline int hrtimer_hres_active(void) ...@@ -509,13 +509,14 @@ static inline int hrtimer_hres_active(void)
* next event * next event
* Called with interrupts disabled and base->lock held * Called with interrupts disabled and base->lock held
*/ */
static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base) static void
hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
{ {
int i; int i;
struct hrtimer_clock_base *base = cpu_base->clock_base; struct hrtimer_clock_base *base = cpu_base->clock_base;
ktime_t expires; ktime_t expires, expires_next;
cpu_base->expires_next.tv64 = KTIME_MAX; expires_next.tv64 = KTIME_MAX;
for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) {
struct hrtimer *timer; struct hrtimer *timer;
...@@ -531,10 +532,15 @@ static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base) ...@@ -531,10 +532,15 @@ static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base)
*/ */
if (expires.tv64 < 0) if (expires.tv64 < 0)
expires.tv64 = 0; expires.tv64 = 0;
if (expires.tv64 < cpu_base->expires_next.tv64) if (expires.tv64 < expires_next.tv64)
cpu_base->expires_next = expires; expires_next = expires;
} }
if (skip_equal && expires_next.tv64 == cpu_base->expires_next.tv64)
return;
cpu_base->expires_next.tv64 = expires_next.tv64;
if (cpu_base->expires_next.tv64 != KTIME_MAX) if (cpu_base->expires_next.tv64 != KTIME_MAX)
tick_program_event(cpu_base->expires_next, 1); tick_program_event(cpu_base->expires_next, 1);
} }
...@@ -617,7 +623,7 @@ static void retrigger_next_event(void *arg) ...@@ -617,7 +623,7 @@ static void retrigger_next_event(void *arg)
base->clock_base[CLOCK_REALTIME].offset = base->clock_base[CLOCK_REALTIME].offset =
timespec_to_ktime(realtime_offset); timespec_to_ktime(realtime_offset);
hrtimer_force_reprogram(base); hrtimer_force_reprogram(base, 0);
spin_unlock(&base->lock); spin_unlock(&base->lock);
} }
...@@ -730,7 +736,8 @@ static int hrtimer_switch_to_hres(void) ...@@ -730,7 +736,8 @@ static int hrtimer_switch_to_hres(void)
static inline int hrtimer_hres_active(void) { return 0; } static inline int hrtimer_hres_active(void) { return 0; }
static inline int hrtimer_is_hres_enabled(void) { return 0; } static inline int hrtimer_is_hres_enabled(void) { return 0; }
static inline int hrtimer_switch_to_hres(void) { return 0; } static inline int hrtimer_switch_to_hres(void) { return 0; }
static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { } static inline void
hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { }
static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
struct hrtimer_clock_base *base, struct hrtimer_clock_base *base,
int wakeup) int wakeup)
...@@ -873,19 +880,29 @@ static void __remove_hrtimer(struct hrtimer *timer, ...@@ -873,19 +880,29 @@ static void __remove_hrtimer(struct hrtimer *timer,
struct hrtimer_clock_base *base, struct hrtimer_clock_base *base,
unsigned long newstate, int reprogram) unsigned long newstate, int reprogram)
{ {
if (timer->state & HRTIMER_STATE_ENQUEUED) { if (!(timer->state & HRTIMER_STATE_ENQUEUED))
/* goto out;
* Remove the timer from the rbtree and replace the
* first entry pointer if necessary. /*
*/ * Remove the timer from the rbtree and replace the first
if (base->first == &timer->node) { * entry pointer if necessary.
base->first = rb_next(&timer->node); */
/* Reprogram the clock event device. if enabled */ if (base->first == &timer->node) {
if (reprogram && hrtimer_hres_active()) base->first = rb_next(&timer->node);
hrtimer_force_reprogram(base->cpu_base); #ifdef CONFIG_HIGH_RES_TIMERS
/* Reprogram the clock event device. if enabled */
if (reprogram && hrtimer_hres_active()) {
ktime_t expires;
expires = ktime_sub(hrtimer_get_expires(timer),
base->offset);
if (base->cpu_base->expires_next.tv64 == expires.tv64)
hrtimer_force_reprogram(base->cpu_base, 1);
} }
rb_erase(&timer->node, &base->active); #endif
} }
rb_erase(&timer->node, &base->active);
out:
timer->state = newstate; timer->state = newstate;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment