[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] SMP timer and irq fixes for 2.6. Merge x86/64 time.c with i386.



ChangeSet 1.1452, 2005/04/05 13:07:37+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        SMP timer and irq fixes for 2.6. Merge x86/64 time.c with i386.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c  |   65 -
 b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c     |  126 --
 b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c   |    4 
 b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/Makefile |    4 
 linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/time.c     |  840 --------------
 5 files changed, 91 insertions(+), 948 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c 
b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    2005-04-05 
09:03:31 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    2005-04-05 
09:03:31 -04:00
@@ -437,21 +437,23 @@
 int cpucount;
 
 
-static irqreturn_t local_debug_interrupt(int irq, void *dev_id,
-                                        struct pt_regs *regs)
+static irqreturn_t ldebug_interrupt(
+       int irq, void *dev_id, struct pt_regs *regs)
 {
-
        return IRQ_HANDLED;
 }
 
-static struct irqaction local_irq_debug = {
-       local_debug_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "ldebug",
-       NULL, NULL
-};
+static DEFINE_PER_CPU(int, ldebug_irq);
+static char ldebug_name[NR_IRQS][15];
 
-void local_setup_debug(void)
+void ldebug_setup(void)
 {
-       (void)setup_irq(bind_virq_to_irq(VIRQ_DEBUG), &local_irq_debug);
+       int cpu = smp_processor_id();
+
+       per_cpu(ldebug_irq, cpu) = bind_virq_to_irq(VIRQ_DEBUG);
+       sprintf(ldebug_name[cpu], "ldebug%d", cpu);
+       BUG_ON(request_irq(per_cpu(ldebug_irq, cpu), ldebug_interrupt,
+                          SA_INTERRUPT, ldebug_name[cpu], NULL));
 }
 
 
@@ -472,7 +474,7 @@
        while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
                rep_nop();
        local_setup_timer();
-       local_setup_debug();    /* XXX */
+       ldebug_setup();
        smp_intr_init();
        local_irq_enable();
        /*
@@ -1329,36 +1331,27 @@
 }
 
 extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *);
-
-static struct irqaction reschedule_irq = {
-       smp_reschedule_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "reschedule",
-       NULL, NULL
-};
-
-extern irqreturn_t smp_invalidate_interrupt(int, void *, struct pt_regs *);
-
-static struct irqaction invalidate_irq = {
-       smp_invalidate_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "invalidate",
-       NULL, NULL
-};
-
 extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *);
 
-static struct irqaction call_function_irq = {
-       smp_call_function_interrupt, SA_INTERRUPT, CPU_MASK_NONE,
-       "call_function", NULL, NULL
-};
+static DEFINE_PER_CPU(int, resched_irq);
+static DEFINE_PER_CPU(int, callfunc_irq);
+static char resched_name[NR_IRQS][15];
+static char callfunc_name[NR_IRQS][15];
 
 void __init smp_intr_init(void)
 {
+       int cpu = smp_processor_id();
 
-       (void)setup_irq(
-           bind_ipi_on_cpu_to_irq(smp_processor_id(), RESCHEDULE_VECTOR),
-           &reschedule_irq);
-       (void)setup_irq(
-           bind_ipi_on_cpu_to_irq(smp_processor_id(), INVALIDATE_TLB_VECTOR),
-           &invalidate_irq);
-       (void)setup_irq(
-           bind_ipi_on_cpu_to_irq(smp_processor_id(), CALL_FUNCTION_VECTOR),
-           &call_function_irq);
+       per_cpu(resched_irq, cpu) =
+               bind_ipi_on_cpu_to_irq(cpu, RESCHEDULE_VECTOR);
+       sprintf(resched_name[cpu], "resched%d", cpu);
+       BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt,
+                          SA_INTERRUPT, resched_name[cpu], NULL));
+
+       per_cpu(callfunc_irq, cpu) =
+               bind_ipi_on_cpu_to_irq(cpu, CALL_FUNCTION_VECTOR);
+       sprintf(callfunc_name[cpu], "callfunc%d", cpu);
+       BUG_ON(request_irq(per_cpu(callfunc_irq, cpu),
+                          smp_call_function_interrupt,
+                          SA_INTERRUPT, callfunc_name[cpu], NULL));
 }
diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c 
b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c       2005-04-05 
09:03:31 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c       2005-04-05 
09:03:31 -04:00
@@ -77,6 +77,15 @@
 
 EXPORT_SYMBOL(jiffies_64);
 
+#if defined(__x86_64__)
+unsigned long vxtime_hz = PIT_TICK_RATE;
+struct vxtime_data __vxtime __section_vxtime;   /* for vsyscalls */
+volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
+unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES;
+struct timespec __xtime __section_xtime;
+struct timezone __sys_tz __section_sys_tz;
+#endif
+
 unsigned long cpu_khz; /* Detected as we calibrate the TSC */
 
 extern unsigned long wall_jiffies;
@@ -111,8 +120,8 @@
 static long last_update_from_xen;   /* UTC seconds when last read Xen clock. */
 
 /* Keep track of last time we did processing/updating of jiffies and xtime. */
-u64 processed_system_time;   /* System time (ns) at last processing. */
-DEFINE_PER_CPU(u64, processed_system_time);
+static u64 processed_system_time;   /* System time (ns) at last processing. */
+static DEFINE_PER_CPU(u64, processed_system_time);
 
 #define NS_PER_TICK (1000000000ULL/HZ)
 
@@ -379,37 +388,49 @@
                                        struct pt_regs *regs)
 {
        time_t wtm_sec, sec;
-       s64 delta, nsec;
+       s64 delta, delta_cpu, nsec;
        long sec_diff, wtm_nsec;
+       int cpu = smp_processor_id();
 
        do {
                __get_time_values_from_xen();
 
-               delta = (s64)(shadow_system_time +
-                             ((s64)cur_timer->get_offset() * 
-                              (s64)NSEC_PER_USEC) -
-                             processed_system_time);
+               delta = delta_cpu = (s64)shadow_system_time +
+                       ((s64)cur_timer->get_offset() * (s64)NSEC_PER_USEC);
+               delta     -= processed_system_time;
+               delta_cpu -= per_cpu(processed_system_time, cpu);
        }
        while (!TIME_VALUES_UP_TO_DATE);
 
-       if (unlikely(delta < 0)) {
-               printk("Timer ISR: Time went backwards: %lld %lld %lld %lld\n",
-                      delta, shadow_system_time,
+       if (unlikely(delta < 0) || unlikely(delta_cpu < 0)) {
+               printk("Timer ISR/%d: Time went backwards: "
+                      "delta=%lld cpu_delta=%lld shadow=%lld "
+                      "off=%lld processed=%lld cpu_processed=%lld\n",
+                      cpu, delta, delta_cpu, shadow_system_time,
                       ((s64)cur_timer->get_offset() * (s64)NSEC_PER_USEC), 
-                      processed_system_time);
+                      processed_system_time,
+                      per_cpu(processed_system_time, cpu));
                return;
        }
 
-       /* Process elapsed jiffies since last call. */
+       /* System-wide jiffy work. */
        while (delta >= NS_PER_TICK) {
                delta -= NS_PER_TICK;
                processed_system_time += NS_PER_TICK;
                do_timer(regs);
+       }
+
+       /* Local CPU jiffy work. */
+       while (delta_cpu >= NS_PER_TICK) {
+               delta_cpu -= NS_PER_TICK;
+               per_cpu(processed_system_time, cpu) += NS_PER_TICK;
                update_process_times(user_mode(regs));
-               if (regs)
-                       profile_tick(CPU_PROFILING, regs);
+               profile_tick(CPU_PROFILING, regs);
        }
 
+       if (cpu != 0)
+               return;
+
        /*
         * Take synchronised time from Xen once a minute if we're not
         * synchronised ourselves, and we haven't chosen to keep an independent
@@ -617,10 +638,10 @@
 #endif
 
 /* Dynamically-mapped IRQ. */
-static int TIMER_IRQ;
+static DEFINE_PER_CPU(int, timer_irq);
 
 static struct irqaction irq_timer = {
-       timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer",
+       timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer0",
        NULL, NULL
 };
 
@@ -642,14 +663,23 @@
        set_normalized_timespec(&wall_to_monotonic,
                -xtime.tv_sec, -xtime.tv_nsec);
        processed_system_time = shadow_system_time;
+       per_cpu(processed_system_time, 0) = processed_system_time;
 
        if (timer_tsc_init.init(NULL) != 0)
                BUG();
        printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
-       TIMER_IRQ = bind_virq_to_irq(VIRQ_TIMER);
+#if defined(__x86_64__)
+       vxtime.mode = VXTIME_TSC;
+       vxtime.quot = (1000000L << 32) / vxtime_hz;
+       vxtime.tsc_quot = (1000L << 32) / cpu_khz;
+       vxtime.hz = vxtime_hz;
+       sync_core();
+       rdtscll(vxtime.last_tsc);
+#endif
 
-       (void)setup_irq(TIMER_IRQ, &irq_timer);
+       per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER);
+       (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
 }
 
 /* Convert jiffies to system time. Call with xtime_lock held for reading. */
@@ -719,6 +749,7 @@
 
        /* Reset our own concept of passage of system time. */
        processed_system_time = shadow_system_time;
+       per_cpu(processed_system_time, 0) = processed_system_time;
 
        /* Accept a warp in UTC (wall-clock) time. */
        last_seen_tv.tv_sec = 0;
@@ -728,63 +759,20 @@
 }
 
 #ifdef CONFIG_SMP
-
-static irqreturn_t local_timer_interrupt(int irq, void *dev_id,
-                                        struct pt_regs *regs)
-{
-       s64 delta;
-       int cpu = smp_processor_id();
-
-       do {

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.