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] SMP timer and irq fixes for 2.6. Merge x86/64 time.c wit

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] SMP timer and irq fixes for 2.6. Merge x86/64 time.c with i386.
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Tue, 05 Apr 2005 12:07:37 +0000
Delivery-date: Tue, 05 Apr 2005 13:03:26 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] SMP timer and irq fixes for 2.6. Merge x86/64 time.c with i386., BitKeeper Bot <=