svn commit: r208494 - in head/sys: amd64/amd64 amd64/include i386/i386 i386/include kern pc98/cbus sys x86/isa x86/x86

Alexander Motin mav at FreeBSD.org
Mon May 24 11:40:50 UTC 2010


Author: mav
Date: Mon May 24 11:40:49 2010
New Revision: 208494
URL: http://svn.freebsd.org/changeset/base/208494

Log:
  - Implement MI helper functions, dividing one or two timer interrupts with
  arbitrary frequencies into hardclock(), statclock() and profclock() calls.
  Same code with minor variations duplicated several times over the tree for
  different timer drivers and architectures.
  - Switch all x86 archs to new functions, simplifying the code and removing
  extra logic from timer drivers. Other archs are also welcome.

Modified:
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/amd64/include/apicvar.h
  head/sys/amd64/include/clock.h
  head/sys/i386/i386/mp_machdep.c
  head/sys/i386/include/apicvar.h
  head/sys/i386/include/clock.h
  head/sys/kern/kern_clock.c
  head/sys/pc98/cbus/clock.c
  head/sys/sys/kernel.h
  head/sys/sys/systm.h
  head/sys/x86/isa/clock.c
  head/sys/x86/x86/local_apic.c

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/amd64/amd64/mp_machdep.c	Mon May 24 11:40:49 2010	(r208494)
@@ -1112,9 +1112,6 @@ ipi_bitmap_handler(struct trapframe fram
 
 	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	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/amd64/include/apicvar.h	Mon May 24 11:40:49 2010	(r208494)
@@ -123,8 +123,7 @@
 #define IPI_PREEMPT     1
 #define IPI_HARDCLOCK   2
 #define IPI_STATCLOCK   3
-#define IPI_PROFCLOCK   4
-#define IPI_BITMAP_LAST IPI_PROFCLOCK
+#define IPI_BITMAP_LAST IPI_STATCLOCK
 #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	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/amd64/include/clock.h	Mon May 24 11:40:49 2010	(r208494)
@@ -27,7 +27,6 @@ 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/i386/mp_machdep.c
==============================================================================
--- head/sys/i386/i386/mp_machdep.c	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/i386/i386/mp_machdep.c	Mon May 24 11:40:49 2010	(r208494)
@@ -1279,9 +1279,6 @@ ipi_bitmap_handler(struct trapframe fram
 
 	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	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/i386/include/apicvar.h	Mon May 24 11:40:49 2010	(r208494)
@@ -124,8 +124,7 @@
 #define IPI_PREEMPT     1
 #define IPI_HARDCLOCK   2 
 #define IPI_STATCLOCK   3 
-#define IPI_PROFCLOCK   4 
-#define IPI_BITMAP_LAST IPI_PROFCLOCK
+#define IPI_BITMAP_LAST IPI_STATCLOCK
 #define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
 
 #define	IPI_STOP	(APIC_IPI_INTS + 7)	/* Stop CPU until restarted. */
@@ -152,8 +151,7 @@
 #define IPI_PREEMPT     1
 #define IPI_HARDCLOCK   2 
 #define IPI_STATCLOCK   3 
-#define IPI_PROFCLOCK   4 
-#define IPI_BITMAP_LAST IPI_PROFCLOCK
+#define IPI_BITMAP_LAST IPI_STATCLOCK
 #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	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/i386/include/clock.h	Mon May 24 11:40:49 2010	(r208494)
@@ -27,7 +27,6 @@ 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/kern/kern_clock.c
==============================================================================
--- head/sys/kern/kern_clock.c	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/kern/kern_clock.c	Mon May 24 11:40:49 2010	(r208494)
@@ -374,6 +374,12 @@ int	profprocs;
 int	ticks;
 int	psratio;
 
+int	timer1hz;
+int	timer2hz;
+static DPCPU_DEFINE(u_int, hard_cnt);
+static DPCPU_DEFINE(u_int, stat_cnt);
+static DPCPU_DEFINE(u_int, prof_cnt);
+
 /*
  * Initialize clock frequencies and start both clocks running.
  */
@@ -403,6 +409,52 @@ initclocks(dummy)
 #endif
 }
 
+void
+timer1clock(int usermode, uintfptr_t pc)
+{
+	u_int *cnt;
+
+	cnt = DPCPU_PTR(hard_cnt);
+	*cnt += hz;
+	if (*cnt >= timer1hz) {
+		*cnt -= timer1hz;
+		if (*cnt >= timer1hz)
+			*cnt = 0;
+		if (PCPU_GET(cpuid) == 0)
+			hardclock(usermode, pc);
+		else
+			hardclock_cpu(usermode);
+	}
+	if (timer2hz == 0)
+		timer2clock(usermode, pc);
+}
+
+void
+timer2clock(int usermode, uintfptr_t pc)
+{
+	u_int *cnt;
+	int t2hz = timer2hz ? timer2hz : timer1hz;
+
+	cnt = DPCPU_PTR(stat_cnt);
+	*cnt += stathz;
+	if (*cnt >= t2hz) {
+		*cnt -= t2hz;
+		if (*cnt >= t2hz)
+			*cnt = 0;
+		statclock(usermode);
+	}
+	if (profprocs == 0)
+		return;
+	cnt = DPCPU_PTR(prof_cnt);
+	*cnt += profhz;
+	if (*cnt >= t2hz) {
+		*cnt -= t2hz;
+		if (*cnt >= t2hz)
+			*cnt = 0;
+			profclock(usermode, pc);
+	}
+}
+
 /*
  * Each time the real-time timer fires, this function is called on all CPUs.
  * Note that hardclock() calls hardclock_cpu() for the boot CPU, so only

Modified: head/sys/pc98/cbus/clock.c
==============================================================================
--- head/sys/pc98/cbus/clock.c	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/pc98/cbus/clock.c	Mon May 24 11:40:49 2010	(r208494)
@@ -129,10 +129,7 @@ int
 hardclockintr(struct trapframe *frame)
 {
 
-	if (PCPU_GET(cpuid) == 0)
-		hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-	else
-		hardclock_cpu(TRAPF_USERMODE(frame));
+	timer1clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	return (FILTER_HANDLED);
 }
 
@@ -143,13 +140,6 @@ statclockintr(struct trapframe *frame)
 	return (FILTER_HANDLED);
 }
 
-int
-profclockintr(struct trapframe *frame)
-{
-
-	return (FILTER_HANDLED);
-}
-
 static int
 clkintr(struct trapframe *frame)
 {
@@ -448,6 +438,7 @@ cpu_initclocks()
 	 * timecounter to user a simpler algorithm.
 	 */
 	if (using_lapic_timer == LAPIC_CLOCK_NONE) {
+		timer1hz = hz;
 		intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL,
 		    NULL, INTR_TYPE_CLK, NULL);
 		i8254_intsrc = intr_lookup_source(0);
@@ -460,6 +451,14 @@ cpu_initclocks()
 		i8254_timecounter.tc_counter_mask = 0xffff;
 		set_i8254_freq(i8254_freq, hz);
 	}
+	if (using_lapic_timer != LAPIC_CLOCK_ALL) {
+		profhz = hz;
+		if (hz < 128)
+			stathz = hz;
+		else
+			stathz = hz / (hz / 128);
+	}
+	timer2hz = 0;
 
 	init_TSC_tc();
 }

Modified: head/sys/sys/kernel.h
==============================================================================
--- head/sys/sys/kernel.h	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/sys/kernel.h	Mon May 24 11:40:49 2010	(r208494)
@@ -64,6 +64,8 @@ extern int stathz;			/* statistics clock
 extern int profhz;			/* profiling clock's frequency */
 extern int profprocs;			/* number of process's profiling */
 extern int ticks;
+extern int timer1hz;			/* timer 1 frequency */
+extern int timer2hz;			/* timer 2 frequency */
 
 #endif /* _KERNEL */
 

Modified: head/sys/sys/systm.h
==============================================================================
--- head/sys/sys/systm.h	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/sys/systm.h	Mon May 24 11:40:49 2010	(r208494)
@@ -240,6 +240,8 @@ void	hardclock_cpu(int usermode);
 void	softclock(void *);
 void	statclock(int usermode);
 void	profclock(int usermode, uintfptr_t pc);
+void	timer1clock(int usermode, uintfptr_t pc);
+void	timer2clock(int usermode, uintfptr_t pc);
 
 void	startprofclock(struct proc *);
 void	stopprofclock(struct proc *);

Modified: head/sys/x86/isa/clock.c
==============================================================================
--- head/sys/x86/isa/clock.c	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/x86/isa/clock.c	Mon May 24 11:40:49 2010	(r208494)
@@ -87,8 +87,6 @@ __FBSDID("$FreeBSD$");
 #define	TIMER_DIV(x) ((i8254_freq + (x) / 2) / (x))
 
 int	clkintr_pending;
-static int pscnt = 1;
-static int psdiv = 1;
 #ifndef TIMER_FREQ
 #define TIMER_FREQ   1193182
 #endif
@@ -134,10 +132,7 @@ int
 hardclockintr(struct trapframe *frame)
 {
 
-	if (PCPU_GET(cpuid) == 0)
-		hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-	else
-		hardclock_cpu(TRAPF_USERMODE(frame));
+	timer1clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	return (FILTER_HANDLED);
 }
 
@@ -145,19 +140,7 @@ int
 statclockintr(struct trapframe *frame)
 {
 
-	profclockintr(frame);
-	statclock(TRAPF_USERMODE(frame));
-	return (FILTER_HANDLED);
-}
-
-int
-profclockintr(struct trapframe *frame)
-{
-
-	if (!using_atrtc_timer)
-		hardclockintr(frame);
-	if (profprocs != 0)
-		profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	timer2clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	return (FILTER_HANDLED);
 }
 
@@ -190,28 +173,11 @@ clkintr(struct trapframe *frame)
 		(*cyclic_clock_func[cpu])(frame);
 #endif
 
-	if (using_atrtc_timer) {
-#ifdef SMP
-		if (smp_started)
-			ipi_all_but_self(IPI_HARDCLOCK);
-#endif
-		hardclockintr(frame);
-	} else {
-		if (--pscnt <= 0) {
-			pscnt = psratio;
 #ifdef SMP
-			if (smp_started)
-				ipi_all_but_self(IPI_STATCLOCK);
+	if (smp_started)
+		ipi_all_but_self(IPI_HARDCLOCK);
 #endif
-			statclockintr(frame);
-		} else {
-#ifdef SMP
-			if (smp_started)
-				ipi_all_but_self(IPI_PROFCLOCK);
-#endif
-			profclockintr(frame);
-		}
-	}
+	hardclockintr(frame);
 
 #ifdef DEV_MCA
 	/* Reset clock interrupt by asserting bit 7 of port 0x61 */
@@ -295,20 +261,11 @@ rtcintr(struct trapframe *frame)
 
 	while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
 		flag = 1;
-		if (--pscnt <= 0) {
-			pscnt = psdiv;
 #ifdef SMP
-			if (smp_started)
-				ipi_all_but_self(IPI_STATCLOCK);
-#endif
-			statclockintr(frame);
-		} else {
-#ifdef SMP
-			if (smp_started)
-				ipi_all_but_self(IPI_PROFCLOCK);
+		if (smp_started)
+			ipi_all_but_self(IPI_STATCLOCK);
 #endif
-			profclockintr(frame);
-		}
+		statclockintr(frame);
 	}
 	return(flag ? FILTER_HANDLED : FILTER_STRAY);
 }
@@ -555,6 +512,7 @@ cpu_initclocks()
 	 * timecounter to user a simpler algorithm.
 	 */
 	if (using_lapic_timer == LAPIC_CLOCK_NONE) {
+		timer1hz = hz;
 		intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL,
 		    NULL, INTR_TYPE_CLK, NULL);
 		i8254_intsrc = intr_lookup_source(0);
@@ -577,6 +535,7 @@ cpu_initclocks()
 	if (using_lapic_timer != LAPIC_CLOCK_ALL) {
 		using_atrtc_timer = tasc; 
 		if (using_atrtc_timer) {
+			timer2hz = RTC_NOPROFRATE;
 			/* Enable periodic interrupts from the RTC. */
 			intr_add_handler("rtc", 8,
 			    (driver_filter_t *)rtcintr, NULL, NULL,
@@ -588,6 +547,7 @@ cpu_initclocks()
 				stathz = hz;
 			else
 				stathz = hz / (hz / 128);
+			timer2hz = 0;
 		}
 	}
 
@@ -601,7 +561,7 @@ cpu_startprofclock(void)
 	if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer)
 		return;
 	atrtc_rate(RTCSA_PROF);
-	psdiv = pscnt = psratio;
+	timer2hz = RTC_PROFRATE;
 }
 
 void
@@ -611,7 +571,7 @@ cpu_stopprofclock(void)
 	if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer)
 		return;
 	atrtc_rate(RTCSA_NOPROF);
-	psdiv = pscnt = 1;
+	timer2hz = RTC_NOPROFRATE;
 }
 
 static int

Modified: head/sys/x86/x86/local_apic.c
==============================================================================
--- head/sys/x86/x86/local_apic.c	Mon May 24 11:14:40 2010	(r208493)
+++ head/sys/x86/x86/local_apic.c	Mon May 24 11:40:49 2010	(r208494)
@@ -118,9 +118,6 @@ struct lapic {
 	u_int la_cluster_id:2;
 	u_int la_present:1;
 	u_long *la_timer_count;
-	u_long la_hard_ticks;
-	u_long la_stat_ticks;
-	u_long la_prof_ticks;
 	/* Include IDT_SYSCALL to make indexing easier. */
 	int la_ioint_irqs[APIC_NUM_IOINTS + 1];
 } static lapics[MAX_APIC_ID + 1];
@@ -493,12 +490,14 @@ lapic_setup_clock(enum lapic_clock srcsd
 	} else
 		lapic_timer_hz = hz;
 	lapic_timer_period = value / lapic_timer_hz;
+	timer1hz = lapic_timer_hz;
 	if (srcsdes == LAPIC_CLOCK_ALL) {
 		if (lapic_timer_hz < 128)
 			stathz = lapic_timer_hz;
 		else
 			stathz = lapic_timer_hz / (lapic_timer_hz / 128);
 		profhz = lapic_timer_hz;
+		timer2hz = 0;
 	}
 
 	/*
@@ -790,33 +789,7 @@ lapic_handle_timer(struct trapframe *fra
 		(*cyclic_clock_func[cpu])(frame);
 #endif
 
-	/* Fire hardclock at hz. */
-	la->la_hard_ticks += hz;
-	if (la->la_hard_ticks >= lapic_timer_hz) {
-		la->la_hard_ticks -= lapic_timer_hz;
-		if (PCPU_GET(cpuid) == 0)
-			hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-		else
-			hardclock_cpu(TRAPF_USERMODE(frame));
-	}
-	if (clockcoverage == LAPIC_CLOCK_ALL) {
-
-		/* Fire statclock at stathz. */
-		la->la_stat_ticks += stathz;
-		if (la->la_stat_ticks >= lapic_timer_hz) {
-			la->la_stat_ticks -= lapic_timer_hz;
-			statclock(TRAPF_USERMODE(frame));
-		}
-
-		/* Fire profclock at profhz, but only when needed. */
-		la->la_prof_ticks += profhz;
-		if (la->la_prof_ticks >= lapic_timer_hz) {
-			la->la_prof_ticks -= lapic_timer_hz;
-			if (profprocs != 0)
-				profclock(TRAPF_USERMODE(frame),
-				    TRAPF_PC(frame));
-		}
-	}
+	timer1clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	critical_exit();
 }
 


More information about the svn-src-head mailing list