Author: mav
Date: Sat May  2 12:20:43 2009
New Revision: 191744
URL: http://svn.freebsd.org/changeset/base/191744

Log:
  Add support for using i8254 and rtc timers as event sources for amd64 SMP
  system. Redistribute hard-/stat-/profclock events to other CPUs using IPIs.

Modified:
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/amd64/include/apicvar.h
  head/sys/amd64/include/clock.h
  head/sys/amd64/isa/clock.c

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c   Sat May  2 11:59:56 2009        
(r191743)
+++ head/sys/amd64/amd64/mp_machdep.c   Sat May  2 12:20:43 2009        
(r191744)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_extern.h>
 
 #include <machine/apicreg.h>
+#include <machine/clock.h>
 #include <machine/cputypes.h>
 #include <machine/cpufunc.h>
 #include <machine/md_var.h>
@@ -1124,6 +1125,15 @@ ipi_bitmap_handler(struct trapframe fram
                sched_preempt(curthread);
 
        /* Nothing to do for AST */
+
+       if (ipi_bitmap & (1 << IPI_HARDCLOCK))
+               hardclockintr(&frame);
+
+       if (ipi_bitmap & (1 << IPI_STATCLOCK))
+               statclockintr(&frame);
+
+       if (ipi_bitmap & (1 << IPI_PROFCLOCK))
+               profclockintr(&frame);
 }
 
 /*

Modified: head/sys/amd64/include/apicvar.h
==============================================================================
--- head/sys/amd64/include/apicvar.h    Sat May  2 11:59:56 2009        
(r191743)
+++ head/sys/amd64/include/apicvar.h    Sat May  2 12:20:43 2009        
(r191744)
@@ -126,7 +126,10 @@
 /* IPIs handled by IPI_BITMAPED_VECTOR  (XXX ups is there a better place?) */
 #define        IPI_AST         0       /* Generate software trap. */
 #define IPI_PREEMPT     1
-#define IPI_BITMAP_LAST IPI_PREEMPT
+#define IPI_HARDCLOCK   2
+#define IPI_STATCLOCK   3
+#define IPI_PROFCLOCK   4
+#define IPI_BITMAP_LAST IPI_PROFCLOCK
 #define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
 
 #define        IPI_STOP        (APIC_IPI_INTS + 7)     /* Stop CPU until 
restarted. */

Modified: head/sys/amd64/include/clock.h
==============================================================================
--- head/sys/amd64/include/clock.h      Sat May  2 11:59:56 2009        
(r191743)
+++ head/sys/amd64/include/clock.h      Sat May  2 12:20:43 2009        
(r191744)
@@ -24,6 +24,12 @@ extern int   tsc_is_invariant;
 
 void   i8254_init(void);
 
+struct trapframe;
+
+int    hardclockintr(struct trapframe *frame);
+int    statclockintr(struct trapframe *frame);
+int    profclockintr(struct trapframe *frame);
+
 /*
  * Driver to clock driver interface.
  */

Modified: head/sys/amd64/isa/clock.c
==============================================================================
--- head/sys/amd64/isa/clock.c  Sat May  2 11:59:56 2009        (r191743)
+++ head/sys/amd64/isa/clock.c  Sat May  2 12:20:43 2009        (r191744)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/sched.h>
+#include <sys/smp.h>
 #include <sys/sysctl.h>
 
 #include <machine/clock.h>
@@ -62,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/apicvar.h>
 #include <machine/ppireg.h>
 #include <machine/timerreg.h>
+#include <machine/smp.h>
 
 #include <isa/rtc.h>
 #ifdef DEV_ISA
@@ -112,6 +114,35 @@ static struct timecounter i8254_timecoun
        0                       /* quality */
 };
 
+int
+hardclockintr(struct trapframe *frame)
+{
+
+       if (PCPU_GET(cpuid) == 0)
+               hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+       else
+               hardclock_cpu(TRAPF_USERMODE(frame));
+       return (FILTER_HANDLED);
+}
+
+int
+statclockintr(struct trapframe *frame)
+{
+
+       if (profprocs != 0)
+               profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+       statclock(TRAPF_USERMODE(frame));
+       return (FILTER_HANDLED);
+}
+
+int
+profclockintr(struct trapframe *frame)
+{
+
+       profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+       return (FILTER_HANDLED);
+}
+
 static int
 clkintr(struct trapframe *frame)
 {
@@ -128,7 +159,14 @@ clkintr(struct trapframe *frame)
                mtx_unlock_spin(&clock_lock);
        }
        KASSERT(!using_lapic_timer, ("clk interrupt enabled with lapic timer"));
-       hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+#ifdef SMP
+       if (smp_started)
+               ipi_all_but_self(IPI_HARDCLOCK);
+#endif
+       if (PCPU_GET(cpuid) == 0)
+               hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+       else
+               hardclock_cpu(TRAPF_USERMODE(frame));
        return (FILTER_HANDLED);
 }
 
@@ -209,10 +247,19 @@ rtcintr(struct trapframe *frame)
                if (profprocs != 0) {
                        if (--pscnt == 0)
                                pscnt = psdiv;
+#ifdef SMP
+                       if (pscnt != psdiv && smp_started)
+                               ipi_all_but_self(IPI_PROFCLOCK);
+#endif
                        profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
                }
-               if (pscnt == psdiv)
+               if (pscnt == psdiv) {
+#ifdef SMP
+                       if (smp_started)
+                               ipi_all_but_self(IPI_STATCLOCK);
+#endif
                        statclock(TRAPF_USERMODE(frame));
+               }
        }
        return(flag ? FILTER_HANDLED : FILTER_STRAY);
 }
_______________________________________________
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