svn commit: r191745 - in head/sys/i386: i386 include isa

Alexander Motin mav at FreeBSD.org
Sat May 2 12:59:48 UTC 2009


Author: mav
Date: Sat May  2 12:59:47 2009
New Revision: 191745
URL: http://svn.freebsd.org/changeset/base/191745

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

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

Modified: head/sys/i386/i386/mp_machdep.c
==============================================================================
--- head/sys/i386/i386/mp_machdep.c	Sat May  2 12:20:43 2009	(r191744)
+++ head/sys/i386/i386/mp_machdep.c	Sat May  2 12:59:47 2009	(r191745)
@@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_extern.h>
 
 #include <machine/apicreg.h>
+#include <machine/clock.h>
 #include <machine/cputypes.h>
 #include <machine/md_var.h>
 #include <machine/mp_watchdog.h>
@@ -1284,6 +1285,15 @@ ipi_bitmap_handler(struct trapframe fram
 #endif
 		/* 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/i386/include/apicvar.h
==============================================================================
--- head/sys/i386/include/apicvar.h	Sat May  2 12:20:43 2009	(r191744)
+++ head/sys/i386/include/apicvar.h	Sat May  2 12:59:47 2009	(r191745)
@@ -137,7 +137,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/i386/include/clock.h
==============================================================================
--- head/sys/i386/include/clock.h	Sat May  2 12:20:43 2009	(r191744)
+++ head/sys/i386/include/clock.h	Sat May  2 12:59:47 2009	(r191745)
@@ -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/i386/isa/clock.c
==============================================================================
--- head/sys/i386/isa/clock.c	Sat May  2 12:20:43 2009	(r191744)
+++ head/sys/i386/isa/clock.c	Sat May  2 12:59:47 2009	(r191745)
@@ -57,6 +57,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>
@@ -69,6 +70,7 @@ __FBSDID("$FreeBSD$");
 #endif
 #include <machine/ppireg.h>
 #include <machine/timerreg.h>
+#include <machine/smp.h>
 
 #include <isa/rtc.h>
 #ifdef DEV_ISA
@@ -127,6 +129,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)
 {
@@ -155,7 +186,14 @@ clkintr(struct trapframe *frame)
 		(*lapic_cyclic_clock_func[cpu])(frame);
 #endif
 
-	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));
 #ifdef DEV_MCA
 	/* Reset clock interrupt by asserting bit 7 of port 0x61 */
 	if (MCA_system)
@@ -241,10 +279,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