svn commit: r191744 - in head/sys/amd64: amd64 include isa

Alexander Motin mav at FreeBSD.org
Sat May 2 12:20:44 UTC 2009


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);
 }


More information about the svn-src-all mailing list