All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>,
	Corey Ashford <cjashfor@linux.vnet.ibm.com>,
	linux-kernel@vger.kernel.org,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Thomas Gleixner <tglx@linutronix.de>
Subject: [PATCH 1/5] hrtimer: per-cpu cached values of ktime
Date: Fri, 08 May 2009 18:52:20 +0200	[thread overview]
Message-ID: <20090508170028.630419454@chello.nl> (raw)
In-Reply-To: 20090508165219.469818319@chello.nl

[-- Attachment #1: opt-tick-ktime_get.patch --]
[-- Type: text/plain, Size: 4197 bytes --]

The regular (hrtimer driven) tick calls ktime_get() 4 times:

hrtimer_interupt()
  ktimer_get()
  __run_hrtimer()
    tick_sched_timer()
      ktimer_get()
      update_process_times()
        run_local_timers()
        rcu_pending()
        printk_tick()
        scheduler_tick()
          sched_clock_tick()
            ktime_get()
          perf_counter_task_tick()
        run_posix_cpu_timers()
      profile_tick()
      hrtimer_forward()
    hrtimer_enqueue()
      tick_program_event()
        tick_dev_program_event()
          ktime_get()

Reduce that to 2 by caching the 1st ktime_get(). By clearing the state on
irq_exit() this always works, even for !hrtimer ticks.

Getting rid of the last ktime_get() is a bit more involved as that code can
also get called from outside of irq context.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 include/linux/hrtimer.h  |    5 +++++
 kernel/hrtimer.c         |   22 ++++++++++++++++++++--
 kernel/sched_clock.c     |    3 ++-
 kernel/softirq.c         |    2 ++
 kernel/time/tick-sched.c |    2 +-
 5 files changed, 30 insertions(+), 4 deletions(-)

Index: linux-2.6/include/linux/hrtimer.h
===================================================================
--- linux-2.6.orig/include/linux/hrtimer.h
+++ linux-2.6/include/linux/hrtimer.h
@@ -173,8 +173,13 @@ struct hrtimer_cpu_base {
 	int				hres_active;
 	unsigned long			nr_events;
 #endif
+	ktime_t				ktime_irq;
+	int				ktime_irq_set;
 };
 
+extern ktime_t ktime_irq_get(void);
+extern void ktime_irq_clear(void);
+
 static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
 {
 	timer->_expires = time;
Index: linux-2.6/kernel/hrtimer.c
===================================================================
--- linux-2.6.orig/kernel/hrtimer.c
+++ linux-2.6/kernel/hrtimer.c
@@ -88,7 +88,6 @@ EXPORT_SYMBOL_GPL(ktime_get_real);
  */
 DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
 {
-
 	.clock_base =
 	{
 		{
@@ -104,6 +103,25 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, 
 	}
 };
 
+ktime_t ktime_irq_get(void)
+{
+	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
+
+	if (!cpu_base->ktime_irq_set) {
+		cpu_base->ktime_irq = ktime_get();
+		cpu_base->ktime_irq_set = 1;
+	}
+
+	return cpu_base->ktime_irq;
+}
+
+void ktime_irq_clear(void)
+{
+	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
+
+	cpu_base->ktime_irq_set = 0;
+}
+
 /**
  * ktime_get_ts - get the monotonic clock in timespec format
  * @ts:		pointer to timespec variable
@@ -1222,7 +1240,7 @@ void hrtimer_interrupt(struct clock_even
 	if (!(++nr_retries % 5))
 		hrtimer_interrupt_hanging(dev, ktime_sub(ktime_get(), now));
 
-	now = ktime_get();
+	now = ktime_irq_get();
 
 	expires_next.tv64 = KTIME_MAX;
 
Index: linux-2.6/kernel/sched_clock.c
===================================================================
--- linux-2.6.orig/kernel/sched_clock.c
+++ linux-2.6/kernel/sched_clock.c
@@ -219,7 +219,7 @@ void sched_clock_tick(void)
 	WARN_ON_ONCE(!irqs_disabled());
 
 	scd = this_scd();
-	now_gtod = ktime_to_ns(ktime_get());
+	now_gtod = ktime_to_ns(ktime_irq_get());
 	now = sched_clock();
 
 	__raw_spin_lock(&scd->lock);
@@ -246,6 +246,7 @@ void sched_clock_idle_wakeup_event(u64 d
 	if (timekeeping_suspended)
 		return;
 
+	ktime_irq_clear();
 	sched_clock_tick();
 	touch_softlockup_watchdog();
 }
Index: linux-2.6/kernel/softirq.c
===================================================================
--- linux-2.6.orig/kernel/softirq.c
+++ linux-2.6/kernel/softirq.c
@@ -282,6 +282,8 @@ void irq_enter(void)
 		tick_check_idle(cpu);
 	} else
 		__irq_enter();
+
+	ktime_irq_clear();
 }
 
 #ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
Index: linux-2.6/kernel/time/tick-sched.c
===================================================================
--- linux-2.6.orig/kernel/time/tick-sched.c
+++ linux-2.6/kernel/time/tick-sched.c
@@ -629,7 +629,7 @@ static enum hrtimer_restart tick_sched_t
 	struct tick_sched *ts =
 		container_of(timer, struct tick_sched, sched_timer);
 	struct pt_regs *regs = get_irq_regs();
-	ktime_t now = ktime_get();
+	ktime_t now = ktime_irq_get();
 	int cpu = smp_processor_id();
 
 #ifdef CONFIG_NO_HZ

-- 


  reply	other threads:[~2009-05-08 18:18 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-08 16:52 [PATCH 0/5] pending patches Peter Zijlstra
2009-05-08 16:52 ` Peter Zijlstra [this message]
2009-05-08 23:10   ` [PATCH 1/5] hrtimer: per-cpu cached values of ktime Andrew Morton
2009-05-09 19:45   ` Linus Torvalds
2009-05-09 19:59     ` Peter Zijlstra
2009-05-08 16:52 ` [PATCH 2/5] perf_counter: optimize perf_counter_task_tick() Peter Zijlstra
2009-05-08 18:39   ` [tip:perfcounters/core] " tip-bot for Peter Zijlstra
2009-05-08 16:52 ` [PATCH 3/5] perf_counter: rework ioctl()s Peter Zijlstra
2009-05-08 18:39   ` [tip:perfcounters/core] " tip-bot for Peter Zijlstra
2009-05-11  1:29   ` [PATCH 3/5] " Paul Mackerras
2009-05-11 15:12     ` Peter Zijlstra
2009-05-12  6:24       ` Paul Mackerras
2009-05-11 18:12     ` Corey Ashford
2009-05-11 20:52       ` Paul Mackerras
2009-05-11 22:37         ` Corey Ashford
2009-05-12  6:16           ` Paul Mackerras
2009-05-12 16:15             ` Corey Ashford
2009-05-12 22:18               ` Paul Mackerras
2009-05-12 22:51                 ` Corey Ashford
2009-05-11 23:58   ` Arnd Bergmann
2009-05-12  6:11     ` Peter Zijlstra
2009-05-12  6:22       ` Paul Mackerras
2009-05-12  6:27         ` Peter Zijlstra
2009-05-12  7:10           ` Peter Zijlstra
2009-05-12  7:52             ` Arnd Bergmann
2009-05-12 10:59               ` [PATCH] perf_counter: fix ioctl()s Peter Zijlstra
2009-05-12 11:21             ` [PATCH 3/5] perf_counter: rework ioctl()s Paul Mackerras
2009-05-08 16:52 ` [PATCH 4/5] perf_counter: PERF_RECORD_CONFIG Peter Zijlstra
2009-05-08 18:39   ` [tip:perfcounters/core] perf_counter: add PERF_RECORD_CONFIG tip-bot for Peter Zijlstra
2009-05-08 16:52 ` [PATCH 5/5] perf_counter: PERF_RECORD_CPU Peter Zijlstra
2009-05-08 18:40   ` [tip:perfcounters/core] perf_counter: add PERF_RECORD_CPU tip-bot for Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090508170028.630419454@chello.nl \
    --to=a.p.zijlstra@chello.nl \
    --cc=cjashfor@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=paulus@samba.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.