Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f507102 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
Loading
Loading
Loading
Loading
+35 −18
Original line number Diff line number Diff line
@@ -509,13 +509,14 @@ static inline int hrtimer_hres_active(void)
 * next event
 * 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;
	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++) {
		struct hrtimer *timer;
@@ -531,10 +532,15 @@ static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base)
		 */
		if (expires.tv64 < 0)
			expires.tv64 = 0;
		if (expires.tv64 < cpu_base->expires_next.tv64)
			cpu_base->expires_next = expires;
		if (expires.tv64 < expires_next.tv64)
			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)
		tick_program_event(cpu_base->expires_next, 1);
}
@@ -617,7 +623,7 @@ static void retrigger_next_event(void *arg)
	base->clock_base[CLOCK_REALTIME].offset =
		timespec_to_ktime(realtime_offset);

	hrtimer_force_reprogram(base);
	hrtimer_force_reprogram(base, 0);
	spin_unlock(&base->lock);
}

@@ -730,7 +736,8 @@ static int hrtimer_switch_to_hres(void)
static inline int hrtimer_hres_active(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 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,
					    struct hrtimer_clock_base *base,
					    int wakeup)
@@ -873,19 +880,29 @@ static void __remove_hrtimer(struct hrtimer *timer,
			     struct hrtimer_clock_base *base,
			     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
	 * entry pointer if necessary.
	 */
	if (base->first == &timer->node) {
		base->first = rb_next(&timer->node);
#ifdef CONFIG_HIGH_RES_TIMERS
		/* Reprogram the clock event device. if enabled */
			if (reprogram && hrtimer_hres_active())
				hrtimer_force_reprogram(base->cpu_base);
		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;
}