WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] First part of timer merge

# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID 89fc07f85b01f15ae00ea4d312352b2d1dd0a075
# Parent  9361694781fcf78e8cb03634d1fdd5dbd4930cf7
First part of timer merge
Signed-off-by Kevin Tian <Kevin.tian@xxxxxxxxx>
Signed-off-by Eddie Dong <Eddie.dong@xxxxxxxxx>

diff -r 9361694781fc -r 89fc07f85b01 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Tue Sep  6 22:21:40 2005
+++ b/xen/arch/ia64/xen/vcpu.c  Tue Sep  6 22:49:01 2005
@@ -1032,6 +1032,8 @@
 
        if (is_idle_task(vcpu->domain)) {
                printf("****** vcpu_set_next_timer called during idle!!\n");
+               vcpu_safe_set_itm(s);
+               return;
        }
        //s = PSCBX(vcpu,xen_itm);
        if (d && (d > now) && (d < s)) {
diff -r 9361694781fc -r 89fc07f85b01 xen/arch/ia64/xen/xenmisc.c
--- a/xen/arch/ia64/xen/xenmisc.c       Tue Sep  6 22:21:40 2005
+++ b/xen/arch/ia64/xen/xenmisc.c       Tue Sep  6 22:49:01 2005
@@ -113,29 +113,6 @@
        printf("__hypercall_create_continuation: not implemented!!!\n");
 }
 #endif
-
-///////////////////////////////
-
-///////////////////////////////
-// from arch/x86/apic.c
-///////////////////////////////
-
-extern unsigned long domain0_ready;
-
-int reprogram_ac_timer(s_time_t timeout)
-{
-       struct vcpu *v = current;
-
-#ifdef CONFIG_VTI
-//     if(VMX_DOMAIN(v))
-               return 1;
-#endif // CONFIG_VTI
-       if (!domain0_ready) return 1;
-       local_cpu_data->itm_next = timeout;
-       if (is_idle_task(v->domain)) vcpu_safe_set_itm(timeout);
-       else vcpu_set_next_timer(current);
-       return 1;
-}
 
 ///////////////////////////////
 // from arch/ia64/page_alloc.c
diff -r 9361694781fc -r 89fc07f85b01 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Tue Sep  6 22:21:40 2005
+++ b/xen/arch/ia64/xen/xensetup.c      Tue Sep  6 22:49:01 2005
@@ -252,11 +252,8 @@
 printk("About to call scheduler_init()\n");
     scheduler_init();
     local_irq_disable();
-printk("About to call xen_time_init()\n");
-    xen_time_init();
-#ifdef CONFIG_VTI
+printk("About to call init_xen_time()\n");
     init_xen_time(); /* initialise the time */
-#endif // CONFIG_VTI 
 printk("About to call ac_timer_init()\n");
     ac_timer_init();
 // init_xen_time(); ???
diff -r 9361694781fc -r 89fc07f85b01 xen/arch/ia64/xen/xentime.c
--- a/xen/arch/ia64/xen/xentime.c       Tue Sep  6 22:21:40 2005
+++ b/xen/arch/ia64/xen/xentime.c       Tue Sep  6 22:49:01 2005
@@ -26,118 +26,78 @@
 #include <asm/sal.h>
 #include <asm/sections.h>
 #include <asm/system.h>
-#ifdef XEN
 #include <asm/vcpu.h>
 #include <linux/jiffies.h>     // not included by xen/sched.h
-#endif
 #include <xen/softirq.h>
 
-#ifdef XEN
 seqlock_t xtime_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED;
-#endif
 
 #define TIME_KEEPER_ID  0
-extern unsigned long wall_jiffies;
-
-static s_time_t        stime_irq;       /* System time at last 'time update' */
-
 unsigned long domain0_ready = 0;
-
-#ifndef CONFIG_VTI
+static s_time_t        stime_irq = 0x0;       /* System time at last 'time 
update' */
+unsigned long itc_scale, ns_scale;
+unsigned long itc_at_irq;
+
 static inline u64 get_time_delta(void)
 {
-       return ia64_get_itc();
-}
-#else // CONFIG_VTI
-static s_time_t        stime_irq = 0x0;       /* System time at last 'time 
update' */
-unsigned long itc_scale;
-unsigned long itc_at_irq;
-static unsigned long   wc_sec, wc_nsec; /* UTC time at last 'time update'.   */
-//static rwlock_t        time_lock = RW_LOCK_UNLOCKED;
-static irqreturn_t vmx_timer_interrupt (int irq, void *dev_id, struct pt_regs 
*regs);
-
-static inline u64 get_time_delta(void)
-{
     s64      delta_itc;
-    u64      delta, cur_itc;
+    u64      cur_itc;
     
     cur_itc = ia64_get_itc();
 
     delta_itc = (s64)(cur_itc - itc_at_irq);
+
+    /* Ensure that the returned system time is monotonically increasing. */
     if ( unlikely(delta_itc < 0) ) delta_itc = 0;
-    delta = ((u64)delta_itc) * itc_scale;
-    delta = delta >> 32;
-
-    return delta;
-}
-
-u64 tick_to_ns(u64 tick)
-{
-    return (tick * itc_scale) >> 32;
-}
-#endif // CONFIG_VTI
+    return cycle_to_ns(delta_itc);
+}
+
+/* We don't expect an absolute cycle value here, since then no way
+ * to prevent overflow for large norminator. Normally this conversion
+ * is used for relative offset.
+ */
+u64 cycle_to_ns(u64 cycle)
+{
+    return (cycle * itc_scale) >> 32;
+}
+
+u64 ns_to_cycle(u64 ns)
+{
+    return (ns * ns_scale) >> 32;
+}
 
 s_time_t get_s_time(void)
 {
     s_time_t now;
-    unsigned long flags;
-
-    read_lock_irqsave(&xtime_lock, flags);
-
-    now = stime_irq + get_time_delta();
-
-    /* Ensure that the returned system time is monotonically increasing. */
-    {
-        static s_time_t prev_now = 0;
-        if ( unlikely(now < prev_now) )
-            now = prev_now;
-        prev_now = now;
-    }
-
-    read_unlock_irqrestore(&xtime_lock, flags);
+    unsigned long flags, seq;
+
+    do {
+       seq = read_seqbegin(&xtime_lock);
+       now = stime_irq + get_time_delta();
+    } while (unlikely(read_seqretry(&xtime_lock, seq)));
 
     return now; 
 }
 
 void update_dom_time(struct vcpu *v)
 {
-// FIXME: implement this?
-//     printf("update_dom_time: called, not implemented, skipping\n");
-       return;
+    /* N-op here, and let dom0 to manage system time directly */
+    return;
 }
 
 /* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
 void do_settime(unsigned long secs, unsigned long nsecs, u64 system_time_base)
 {
-#ifdef  CONFIG_VTI
-    u64 _nsecs;
-
-    write_lock_irq(&xtime_lock);
-
-    _nsecs = (u64)nsecs + (s64)(stime_irq - system_time_base);
-    while ( _nsecs >= 1000000000 ) 
-    {
-        _nsecs -= 1000000000;
-        secs++;
-    }
-
-    wc_sec  = secs;
-    wc_nsec = (unsigned long)_nsecs;
-
-    write_unlock_irq(&xtime_lock);
-
-    update_dom_time(current->domain);
-#else
-// FIXME: Should this be do_settimeofday (from linux)???
-       printf("do_settime: called, not implemented, stopping\n");
-       dummy();
-#endif
+    /* If absolute system time is managed by dom0, there's no need for such
+     * action since only virtual itc/itm service is provided.
+     */
+    return;
 }
 
 irqreturn_t
 xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
-       unsigned long new_itm;
+       unsigned long new_itm, old_itc;
 
 #define HEARTBEAT_FREQ 16      // period in seconds
 #ifdef HEARTBEAT_FREQ
@@ -150,12 +110,6 @@
                count = 0;
        }
 #endif
-#ifndef XEN
-       if (unlikely(cpu_is_offline(smp_processor_id()))) {
-               return IRQ_HANDLED;
-       }
-#endif
-#ifdef XEN
        if (current->domain == dom0) {
                // FIXME: there's gotta be a better way of doing this...
                // We have to ensure that domain0 is launched before we
@@ -176,35 +130,12 @@
                        vcpu_wake(current);
                }
        }
-       raise_actimer_softirq();
-#endif
-
-#ifndef XEN
-       platform_timer_interrupt(irq, dev_id, regs);
-#endif
-
        new_itm = local_cpu_data->itm_next;
 
        if (!time_after(ia64_get_itc(), new_itm))
-#ifdef XEN
                return;
-#else
-               printk(KERN_ERR "Oops: timer tick before it's due 
(itc=%lx,itm=%lx)\n",
-                      ia64_get_itc(), new_itm);
-#endif
-
-#ifdef XEN
-//     printf("GOT TO HERE!!!!!!!!!!!\n");
-       //while(1);
-#else
-       profile_tick(CPU_PROFILING, regs);
-#endif
 
        while (1) {
-#ifndef XEN
-               update_process_times(user_mode(regs));
-#endif
-
                new_itm += local_cpu_data->itm_delta;
 
                if (smp_processor_id() == TIME_KEEPER_ID) {
@@ -221,6 +152,12 @@
                        do_timer(regs);
 #endif
                        local_cpu_data->itm_next = new_itm;
+
+                       /* Updates system time (nanoseconds since boot). */
+                       old_itc = itc_at_irq;
+                       itc_at_irq = ia64_get_itc();
+                       stime_irq += cycle_to_ns(itc_at_irq - old_itc);
+
 #ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
                        write_sequnlock(&xtime_lock);
 #endif
@@ -251,132 +188,65 @@
 //#endif
                /* double check, in case we got hit by a (slow) PMI: */
        } while (time_after_eq(ia64_get_itc(), new_itm));
+       raise_softirq(AC_TIMER_SOFTIRQ);
+
        return IRQ_HANDLED;
 }
 
 static struct irqaction xen_timer_irqaction = {
-#ifdef CONFIG_VTI
-       .handler =      vmx_timer_interrupt,
-#else // CONFIG_VTI
        .handler =      xen_timer_interrupt,
-#endif // CONFIG_VTI
-#ifndef XEN
-       .flags =        SA_INTERRUPT,
-#endif
        .name =         "timer"
 };
 
 void __init
-xen_time_init (void)
+ia64_time_init (void)
 {
        register_percpu_irq(IA64_TIMER_VECTOR, &xen_timer_irqaction);
        ia64_init_itm();
 }
 
 
-#ifdef CONFIG_VTI
-
 /* Late init function (after all CPUs are booted). */
 int __init init_xen_time()
 {
     struct timespec tm;
 
+    ia64_time_init();
     itc_scale  = 1000000000UL << 32 ;
     itc_scale /= local_cpu_data->itc_freq;
+    ns_scale = (local_cpu_data->itc_freq << 32) / 1000000000UL;
 
     /* System time ticks from zero. */
     stime_irq = (s_time_t)0;
     itc_at_irq = ia64_get_itc();
 
-    /* Wallclock time starts as the initial RTC time. */
-    efi_gettimeofday(&tm);
-    wc_sec  = tm.tv_sec;
-    wc_nsec = tm.tv_nsec;
-
-
     printk("Time init:\n");
     printk(".... System Time: %ldns\n", NOW());
     printk(".... scale:       %16lX\n", itc_scale);
-    printk(".... Wall Clock:  %lds %ldus\n", wc_sec, wc_nsec/1000);
 
     return 0;
 }
 
-static irqreturn_t
-vmx_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
-{
-    unsigned long new_itm;
-    struct vcpu *v = current;
-
-
-    new_itm = local_cpu_data->itm_next;
-
-    if (!time_after(ia64_get_itc(), new_itm))
-        return;
-
-    while (1) {
-#ifdef CONFIG_SMP
-        /*
-         * For UP, this is done in do_timer().  Weird, but
-         * fixing that would require updates to all
-         * platforms.
-         */
-        update_process_times(user_mode(v, regs));
-#endif
-        new_itm += local_cpu_data->itm_delta;
-
-        if (smp_processor_id() == TIME_KEEPER_ID) {
-            /*
-             * Here we are in the timer irq handler. We have irqs locally
-             * disabled, but we don't know if the timer_bh is running on
-             * another CPU. We need to avoid to SMP race by acquiring the
-             * xtime_lock.
-             */
-            local_cpu_data->itm_next = new_itm;
-            
-            write_lock_irq(&xtime_lock);
-            /* Update jiffies counter. */
-            (*(unsigned long *)&jiffies_64)++;
-
-            /* Update wall time. */
-            wc_nsec += 1000000000/HZ;
-            if ( wc_nsec >= 1000000000 )
-            {
-                wc_nsec -= 1000000000;
-                wc_sec++;
-            }
-
-            /* Updates system time (nanoseconds since boot). */
-            stime_irq += MILLISECS(1000/HZ);
-            itc_at_irq = ia64_get_itc();
-
-            write_unlock_irq(&xtime_lock);
-            
-        } else
-            local_cpu_data->itm_next = new_itm;
-
-        if (time_after(new_itm, ia64_get_itc()))
-            break;
-    }
-
-    do {
-        /*
-         * If we're too close to the next clock tick for
-         * comfort, we increase the safety margin by
-         * intentionally dropping the next tick(s).  We do NOT
-         * update itm.next because that would force us to call
-         * do_timer() which in turn would let our clock run
-         * too fast (with the potentially devastating effect
-         * of losing monotony of time).
-         */
-        while (!time_after(new_itm, ia64_get_itc() + 
local_cpu_data->itm_delta/2))
-            new_itm += local_cpu_data->itm_delta;
-        ia64_set_itm(new_itm);
-        /* double check, in case we got hit by a (slow) PMI: */
-    } while (time_after_eq(ia64_get_itc(), new_itm));
-    raise_softirq(AC_TIMER_SOFTIRQ);
-    
-    return IRQ_HANDLED;
-}
-#endif // CONFIG_VTI
-
+int reprogram_ac_timer(s_time_t timeout)
+{
+       struct vcpu *v = current;
+       s_time_t expire;
+       unsigned long seq, cur_itc, itm_next;
+
+       if (!domain0_ready) return 1;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+               if ((expire = timeout - NOW()) < 0)
+                       return 0;
+
+               cur_itc = ia64_get_itc();
+               itm_next = cur_itc + ns_to_cycle(expire);
+       } while (unlikely(read_seqretry(&xtime_lock, seq)));
+
+       local_cpu_data->itm_next = itm_next;
+       vcpu_set_next_timer(current);
+       return 1;
+}
+
+

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] First part of timer merge, Xen patchbot -unstable <=