Author: marcel
Date: Fri Mar 26 02:29:15 2010
New Revision: 205665
URL: http://svn.freebsd.org/changeset/base/205665

Log:
  Only use the interval timer for clock interrupts on the BSP and
  have the BSP use IPIs to trigger clock interrupts on the APs.
  This allows us to run on hardware configurations for which the
  ITC has non-uniform frequencies across CPUs.
  
  While here, change the clock XIV to type IPI so as to protect
  the interrupt delivery against CPU re-balancing once that's
  implemented.

Modified:
  head/sys/ia64/ia64/clock.c
  head/sys/ia64/ia64/mp_machdep.c
  head/sys/ia64/include/pcpu.h

Modified: head/sys/ia64/ia64/clock.c
==============================================================================
--- head/sys/ia64/ia64/clock.c  Fri Mar 26 01:57:12 2010        (r205664)
+++ head/sys/ia64/ia64/clock.c  Fri Mar 26 02:29:15 2010        (r205665)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 #include <machine/intrcnt.h>
 #include <machine/md_var.h>
+#include <machine/smp.h>
 
 SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics");
 
@@ -91,58 +92,61 @@ ia64_ih_clock(struct thread *td, u_int x
        int count;
 
        PCPU_INC(md.stats.pcs_nclks);
-       intrcnt[INTRCNT_CLOCK]++;
 
-       itc = ia64_get_itc();
-
-       adj = PCPU_GET(md.clockadj);
-       clk = PCPU_GET(md.clock);
-
-       delta = itc - clk;
-       count = 0;
-       while (delta >= ia64_clock_reload) {
-               /* Only the BSP runs the real clock */
-               if (PCPU_GET(cpuid) == 0)
+       if (PCPU_GET(cpuid) == 0) {
+               /*
+                * Clock processing on the BSP.
+                */
+               intrcnt[INTRCNT_CLOCK]++;
+
+               itc = ia64_get_itc();
+
+               adj = PCPU_GET(md.clockadj);
+               clk = PCPU_GET(md.clock);
+
+               delta = itc - clk;
+               count = 0;
+               while (delta >= ia64_clock_reload) {
+#ifdef SMP
+                       ipi_all_but_self(ia64_clock_xiv);
+#endif
                        hardclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
-               else
-                       hardclock_cpu(TRAPF_USERMODE(tf));
+                       if (profprocs != 0)
+                               profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
+                       statclock(TRAPF_USERMODE(tf));
+                       delta -= ia64_clock_reload;
+                       clk += ia64_clock_reload;
+                       if (adj != 0)
+                               adjust_ticks++;
+                       count++;
+               }
+               ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj);
+               ia64_srlz_d();
+               if (count > 0) {
+                       adjust_lost += count - 1;
+                       if (delta > (ia64_clock_reload >> 3)) {
+                               if (adj == 0)
+                                       adjust_edges++;
+                               adj = ia64_clock_reload >> 4;
+                       } else
+                               adj = 0;
+               } else {
+                       adj = 0;
+                       adjust_excess++;
+               }
+               PCPU_SET(md.clock, clk);
+               PCPU_SET(md.clockadj, adj);
+       } else {
+               /*
+                * Clock processing on the BSP.
+                */
+               hardclock_cpu(TRAPF_USERMODE(tf));
                if (profprocs != 0)
                        profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
                statclock(TRAPF_USERMODE(tf));
-               delta -= ia64_clock_reload;
-               clk += ia64_clock_reload;
-               if (adj != 0)
-                       adjust_ticks++;
-               count++;
        }
-       ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj);
-       ia64_srlz_d();
-       if (count > 0) {
-               adjust_lost += count - 1;
-               if (delta > (ia64_clock_reload >> 3)) {
-                       if (adj == 0)
-                               adjust_edges++;
-                       adj = ia64_clock_reload >> 4;
-               } else
-                       adj = 0;
-       } else {
-               adj = 0;
-               adjust_excess++;
-       }
-       PCPU_SET(md.clock, clk);
-       PCPU_SET(md.clockadj, adj);
-       return (0);
-}
 
-void
-pcpu_initclock(void)
-{
-
-       PCPU_SET(md.clockadj, 0);
-       PCPU_SET(md.clock, ia64_get_itc());
-       ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
-       ia64_set_itv(ia64_clock_xiv);
-       ia64_srlz_d();
+       return (0);
 }
 
 /*
@@ -154,7 +158,7 @@ cpu_initclocks()
 {
        u_long itc_freq;
 
-       ia64_clock_xiv = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IRQ,
+       ia64_clock_xiv = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI,
            ia64_ih_clock);
        if (ia64_clock_xiv == 0)
                panic("No XIV for clock interrupts");
@@ -169,7 +173,11 @@ cpu_initclocks()
        tc_init(&ia64_timecounter);
 #endif
 
-       pcpu_initclock();
+       PCPU_SET(md.clockadj, 0);
+       PCPU_SET(md.clock, ia64_get_itc());
+       ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
+       ia64_set_itv(ia64_clock_xiv);
+       ia64_srlz_d();
 }
 
 void

Modified: head/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- head/sys/ia64/ia64/mp_machdep.c     Fri Mar 26 01:57:12 2010        
(r205664)
+++ head/sys/ia64/ia64/mp_machdep.c     Fri Mar 26 02:29:15 2010        
(r205665)
@@ -206,9 +206,8 @@ ia64_ap_startup(void)
 
        CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid));
 
-       /* kick off the clock on this AP */
-       pcpu_initclock();
-
+       /* Mask interval timer interrupts on APs. */
+       ia64_set_itv(0x10000);
        ia64_set_tpr(0);
        ia64_srlz_d();
        enable_intr();

Modified: head/sys/ia64/include/pcpu.h
==============================================================================
--- head/sys/ia64/include/pcpu.h        Fri Mar 26 01:57:12 2010        
(r205664)
+++ head/sys/ia64/include/pcpu.h        Fri Mar 26 02:29:15 2010        
(r205665)
@@ -91,8 +91,6 @@ __curthread(void)
 #define        PCPU_PTR(member)        (&pcpup->pc_ ## member)
 #define        PCPU_SET(member,value)  (pcpup->pc_ ## member = (value))
 
-void pcpu_initclock(void);
-
 #endif /* _KERNEL */
 
 #endif /* !_MACHINE_PCPU_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to