]> err.no Git - linux-2.6/blobdiff - kernel/timer.c
Merge branch 'e1000' of ssh://198.78.49.142/srv/git/intel/linux-2.6
[linux-2.6] / kernel / timer.c
index cc18857601e2e6a67525d1cd1df94e372304efef..fe3a9a9f832849bddbb3bf1be92268af99287aa9 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/posix-timers.h>
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
+#include <linux/delay.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -46,6 +47,10 @@ static void time_interpolator_update(long delta_nsec);
 #define time_interpolator_update(x)
 #endif
 
+u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
 /*
  * per-CPU timer vector definitions:
  */
@@ -91,30 +96,6 @@ static inline void set_running_timer(tvec_base_t *base,
 #endif
 }
 
-static void check_timer_failed(struct timer_list *timer)
-{
-       static int whine_count;
-       if (whine_count < 16) {
-               whine_count++;
-               printk("Uninitialised timer!\n");
-               printk("This is just a warning.  Your computer is OK\n");
-               printk("function=0x%p, data=0x%lx\n",
-                       timer->function, timer->data);
-               dump_stack();
-       }
-       /*
-        * Now fix it up
-        */
-       timer->magic = TIMER_MAGIC;
-}
-
-static inline void check_timer(struct timer_list *timer)
-{
-       if (timer->magic != TIMER_MAGIC)
-               check_timer_failed(timer);
-}
-
-
 static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
 {
        unsigned long expires = timer->expires;
@@ -177,7 +158,6 @@ void fastcall init_timer(struct timer_list *timer)
 {
        timer->entry.next = NULL;
        timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base;
-       timer->magic = TIMER_MAGIC;
 }
 EXPORT_SYMBOL(init_timer);
 
@@ -230,7 +210,6 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
        int ret = 0;
 
        BUG_ON(!timer->function);
-       check_timer(timer);
 
        base = lock_timer_base(timer, &flags);
 
@@ -283,9 +262,6 @@ void add_timer_on(struct timer_list *timer, int cpu)
        unsigned long flags;
 
        BUG_ON(timer_pending(timer) || !timer->function);
-
-       check_timer(timer);
-
        spin_lock_irqsave(&base->t_base.lock, flags);
        timer->base = &base->t_base;
        internal_add_timer(base, timer);
@@ -316,8 +292,6 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
 {
        BUG_ON(!timer->function);
 
-       check_timer(timer);
-
        /*
         * This is a common optimization triggered by the
         * networking code - if the timer is re-modified
@@ -348,8 +322,6 @@ int del_timer(struct timer_list *timer)
        unsigned long flags;
        int ret = 0;
 
-       check_timer(timer);
-
        if (timer_pending(timer)) {
                base = lock_timer_base(timer, &flags);
                if (timer_pending(timer)) {
@@ -412,8 +384,6 @@ out:
  */
 int del_timer_sync(struct timer_list *timer)
 {
-       check_timer(timer);
-
        for (;;) {
                int ret = try_to_del_timer_sync(timer);
                if (ret >= 0)
@@ -525,7 +495,7 @@ unsigned long next_timer_interrupt(void)
        base = &__get_cpu_var(tvec_bases);
        spin_lock(&base->t_base.lock);
        expires = base->timer_jiffies + (LONG_MAX >> 1);
-       list = 0;
+       list = NULL;
 
        /* Look for timer events in tv1. */
        j = base->timer_jiffies & TVR_MASK;
@@ -747,12 +717,16 @@ static void second_overflow(void)
 #endif
 }
 
-/* in the NTP reference this is called "hardclock()" */
-static void update_wall_time_one_tick(void)
+/*
+ * Returns how many microseconds we need to add to xtime this tick
+ * in doing an adjustment requested with adjtime.
+ */
+static long adjtime_adjustment(void)
 {
-       long time_adjust_step, delta_nsec;
+       long time_adjust_step;
 
-       if ((time_adjust_step = time_adjust) != 0 ) {
+       time_adjust_step = time_adjust;
+       if (time_adjust_step) {
                /*
                 * We are doing an adjtime thing.  Prepare time_adjust_step to
                 * be within bounds.  Note that a positive time_adjust means we
@@ -763,10 +737,19 @@ static void update_wall_time_one_tick(void)
                 */
                time_adjust_step = min(time_adjust_step, (long)tickadj);
                time_adjust_step = max(time_adjust_step, (long)-tickadj);
+       }
+       return time_adjust_step;
+}
+
+/* in the NTP reference this is called "hardclock()" */
+static void update_wall_time_one_tick(void)
+{
+       long time_adjust_step, delta_nsec;
 
+       time_adjust_step = adjtime_adjustment();
+       if (time_adjust_step)
                /* Reduce by this step the amount of time left  */
                time_adjust -= time_adjust_step;
-       }
        delta_nsec = tick_nsec + time_adjust_step * 1000;
        /*
         * Advance the phase, once it gets to one microsecond, then
@@ -788,6 +771,22 @@ static void update_wall_time_one_tick(void)
        }
 }
 
+/*
+ * Return how long ticks are at the moment, that is, how much time
+ * update_wall_time_one_tick will add to xtime next time we call it
+ * (assuming no calls to do_adjtimex in the meantime).
+ * The return value is in fixed-point nanoseconds with SHIFT_SCALE-10
+ * bits to the right of the binary point.
+ * This function has no side-effects.
+ */
+u64 current_tick_length(void)
+{
+       long delta_nsec;
+
+       delta_nsec = tick_nsec + adjtime_adjustment() * 1000;
+       return ((u64) delta_nsec << (SHIFT_SCALE - 10)) + time_adj;
+}
+
 /*
  * Using a loop looks inefficient, but "ticks" is
  * usually just one (we shouldn't be losing ticks,
@@ -888,6 +887,7 @@ static void run_timer_softirq(struct softirq_action *h)
 {
        tvec_base_t *base = &__get_cpu_var(tvec_bases);
 
+       hrtimer_run_queues();
        if (time_after_eq(jiffies, base->timer_jiffies))
                __run_timers(base);
 }
@@ -1149,62 +1149,6 @@ asmlinkage long sys_gettid(void)
        return current->pid;
 }
 
-static long __sched nanosleep_restart(struct restart_block *restart)
-{
-       unsigned long expire = restart->arg0, now = jiffies;
-       struct timespec __user *rmtp = (struct timespec __user *) restart->arg1;
-       long ret;
-
-       /* Did it expire while we handled signals? */
-       if (!time_after(expire, now))
-               return 0;
-
-       expire = schedule_timeout_interruptible(expire - now);
-
-       ret = 0;
-       if (expire) {
-               struct timespec t;
-               jiffies_to_timespec(expire, &t);
-
-               ret = -ERESTART_RESTARTBLOCK;
-               if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
-                       ret = -EFAULT;
-               /* The 'restart' block is already filled in */
-       }
-       return ret;
-}
-
-asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
-{
-       struct timespec t;
-       unsigned long expire;
-       long ret;
-
-       if (copy_from_user(&t, rqtp, sizeof(t)))
-               return -EFAULT;
-
-       if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
-               return -EINVAL;
-
-       expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-       expire = schedule_timeout_interruptible(expire);
-
-       ret = 0;
-       if (expire) {
-               struct restart_block *restart;
-               jiffies_to_timespec(expire, &t);
-               if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
-                       return -EFAULT;
-
-               restart = &current_thread_info()->restart_block;
-               restart->fn = nanosleep_restart;
-               restart->arg0 = jiffies + expire;
-               restart->arg1 = (unsigned long) rmtp;
-               ret = -ERESTART_RESTARTBLOCK;
-       }
-       return ret;
-}
-
 /*
  * sys_sysinfo - fill in sysinfo struct
  */