Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Mar 2010 02:29:15 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r205665 - in head/sys/ia64: ia64 include
Message-ID:  <201003260229.o2Q2TFS1008347@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003260229.o2Q2TFS1008347>