Merge branch 'sched/clock' into tracing/ftrace
authorIngo Molnar <mingo@elte.hu>
Thu, 26 Feb 2009 20:21:59 +0000 (21:21 +0100)
committerIngo Molnar <mingo@elte.hu>
Fri, 27 Feb 2009 07:35:19 +0000 (08:35 +0100)
Conflicts:
kernel/sched_clock.c

1  2 
include/linux/sched.h
kernel/sched_clock.c

diff --combined include/linux/sched.h
@@@ -137,8 -137,6 +137,8 @@@ extern unsigned long nr_uninterruptible
  extern unsigned long nr_active(void);
  extern unsigned long nr_iowait(void);
  
 +extern unsigned long get_parent_ip(unsigned long addr);
 +
  struct seq_file;
  struct cfs_rq;
  struct task_group;
@@@ -1672,6 -1670,16 +1672,16 @@@ static inline int set_cpus_allowed(stru
        return set_cpus_allowed_ptr(p, &new_mask);
  }
  
+ /*
+  * Architectures can set this to 1 if they have specified
+  * CONFIG_HAVE_UNSTABLE_SCHED_CLOCK in their arch Kconfig,
+  * but then during bootup it turns out that sched_clock()
+  * is reliable after all:
+  */
+ #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
+ extern int sched_clock_stable;
+ #endif
  extern unsigned long long sched_clock(void);
  
  extern void sched_clock_init(void);
diff --combined kernel/sched_clock.c
   * The clock: sched_clock_cpu() is monotonic per cpu, and should be somewhat
   * consistent between cpus (never more than 2 jiffies difference).
   */
- #include <linux/sched.h>
- #include <linux/percpu.h>
  #include <linux/spinlock.h>
- #include <linux/ktime.h>
- #include <linux/module.h>
 +#include <linux/hardirq.h>
+ #include <linux/module.h>
+ #include <linux/percpu.h>
+ #include <linux/ktime.h>
+ #include <linux/sched.h>
  
  /*
   * Scheduler clock - returns current time in nanosec units.
@@@ -44,6 -43,10 +44,10 @@@ unsigned long long __attribute__((weak)
  static __read_mostly int sched_clock_running;
  
  #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
+ __read_mostly int sched_clock_stable;
+ #else
+ static const int sched_clock_stable = 1;
+ #endif
  
  struct sched_clock_data {
        /*
@@@ -88,7 -91,7 +92,7 @@@ void sched_clock_init(void
  }
  
  /*
-  * min,max except they take wrapping into account
+  * min, max except they take wrapping into account
   */
  
  static inline u64 wrap_min(u64 x, u64 y)
@@@ -117,10 -120,13 +121,13 @@@ static u64 __update_sched_clock(struct 
        if (unlikely(delta < 0))
                delta = 0;
  
+       if (unlikely(!sched_clock_running))
+               return 0ull;
        /*
         * scd->clock = clamp(scd->tick_gtod + delta,
-        *                    max(scd->tick_gtod, scd->clock),
-        *                    scd->tick_gtod + TICK_NSEC);
+        *                    max(scd->tick_gtod, scd->clock),
+        *                    scd->tick_gtod + TICK_NSEC);
         */
  
        clock = scd->tick_gtod + delta;
@@@ -149,19 -155,13 +156,24 @@@ static void lock_double_clock(struct sc
  
  u64 sched_clock_cpu(int cpu)
  {
-       struct sched_clock_data *scd = cpu_sdc(cpu);
        u64 now, clock, this_clock, remote_clock;
+       struct sched_clock_data *scd;
+       if (sched_clock_stable)
+               return sched_clock();
+       scd = cpu_sdc(cpu);
 +
 +      /*
 +       * Normally this is not called in NMI context - but if it is,
 +       * trying to do any locking here is totally lethal.
 +       */
 +      if (unlikely(in_nmi()))
 +              return scd->clock;
 +
 +      if (unlikely(!sched_clock_running))
 +              return 0ull;
 +
        WARN_ON_ONCE(!irqs_disabled());
        now = sched_clock();
  
        return clock;
  }
  
+ #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
  void sched_clock_tick(void)
  {
        struct sched_clock_data *scd = this_scd();
@@@ -243,22 -245,7 +257,7 @@@ void sched_clock_idle_wakeup_event(u64 
  }
  EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
  
- #else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
- void sched_clock_init(void)
- {
-       sched_clock_running = 1;
- }
- u64 sched_clock_cpu(int cpu)
- {
-       if (unlikely(!sched_clock_running))
-               return 0;
-       return sched_clock();
- }
- #endif
+ #endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
  
  unsigned long long cpu_clock(int cpu)
  {