svn commit: r193814 - in head/sys: amd64/isa i386/isa

Ariff Abdullah ariff at FreeBSD.org
Tue Jun 9 07:26:53 UTC 2009


Author: ariff
Date: Tue Jun  9 07:26:52 2009
New Revision: 193814
URL: http://svn.freebsd.org/changeset/base/193814

Log:
  When using i8254 as the only kernel timer source:
  
  - Interpolate stat/prof clock using clkintr() in a similar fashion to
    local APIC timer, since statclock usually run slower.
  
  - Liberate hardclockintr() from taking the burden of handling both stat
    and prof clock interrupt. Instead, send IPIs within clkintr() to handle
    those.

Modified:
  head/sys/amd64/isa/clock.c
  head/sys/i386/isa/clock.c

Modified: head/sys/amd64/isa/clock.c
==============================================================================
--- head/sys/amd64/isa/clock.c	Tue Jun  9 07:14:32 2009	(r193813)
+++ head/sys/amd64/isa/clock.c	Tue Jun  9 07:26:52 2009	(r193814)
@@ -93,6 +93,9 @@ static	int	i8254_ticked;
 static	int	using_atrtc_timer;
 static	int	using_lapic_timer;
 
+static	u_int	stat_ticks = 0;
+static	u_int	prof_ticks = 0;
+
 /* Values for timerX_state: */
 #define	RELEASED	0
 #define	RELEASE_PENDING	1
@@ -122,8 +125,6 @@ hardclockintr(struct trapframe *frame)
 		hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	else
 		hardclock_cpu(TRAPF_USERMODE(frame));
-	if (!using_atrtc_timer)
-		statclockintr(frame);
 	return (FILTER_HANDLED);
 }
 
@@ -131,8 +132,6 @@ int
 statclockintr(struct trapframe *frame)
 {
 
-	if (profprocs != 0)
-		profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	statclock(TRAPF_USERMODE(frame));
 	return (FILTER_HANDLED);
 }
@@ -166,6 +165,30 @@ clkintr(struct trapframe *frame)
 		ipi_all_but_self(IPI_HARDCLOCK);
 #endif
 	hardclockintr(frame);
+
+	if (!using_atrtc_timer) {
+		prof_ticks += profhz;
+		if (prof_ticks >= hz) {
+			prof_ticks -= hz;
+			if (profprocs != 0) {
+#ifdef SMP
+				if (smp_started)
+					ipi_all_but_self(IPI_PROFCLOCK);
+#endif
+				profclockintr(frame);
+			}
+		}
+		stat_ticks += stathz;
+		if (stat_ticks >= hz) {
+			stat_ticks -= hz;
+#ifdef SMP
+			if (smp_started)
+				ipi_all_but_self(IPI_STATCLOCK);
+#endif
+			statclockintr(frame);
+		}
+	}
+
 	return (FILTER_HANDLED);
 }
 
@@ -500,7 +523,8 @@ cpu_initclocks()
 			    INTR_TYPE_CLK, NULL);
 			atrtc_enable_intr();
 		} else {
-			profhz = stathz = hz;
+			profhz = min(RTC_PROFRATE, hz);
+			stathz = min(RTC_NOPROFRATE, hz);
 		}
 	}
 
@@ -511,7 +535,7 @@ void
 cpu_startprofclock(void)
 {
 
-	if (using_lapic_timer)
+	if (using_lapic_timer || !using_atrtc_clock)
 		return;
 	atrtc_rate(RTCSA_PROF);
 	psdiv = pscnt = psratio;
@@ -521,7 +545,7 @@ void
 cpu_stopprofclock(void)
 {
 
-	if (using_lapic_timer)
+	if (using_lapic_timer || !using_atrtc_clock)
 		return;
 	atrtc_rate(RTCSA_NOPROF);
 	psdiv = pscnt = 1;

Modified: head/sys/i386/isa/clock.c
==============================================================================
--- head/sys/i386/isa/clock.c	Tue Jun  9 07:14:32 2009	(r193813)
+++ head/sys/i386/isa/clock.c	Tue Jun  9 07:26:52 2009	(r193814)
@@ -108,6 +108,9 @@ static	int	i8254_ticked;
 static	int	using_atrtc_timer;
 static	int	using_lapic_timer;
 
+static	u_int	stat_ticks = 0;
+static	u_int	prof_ticks = 0;
+
 /* Values for timerX_state: */
 #define	RELEASED	0
 #define	RELEASE_PENDING	1
@@ -137,8 +140,6 @@ hardclockintr(struct trapframe *frame)
 		hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	else
 		hardclock_cpu(TRAPF_USERMODE(frame));
-	if (!using_atrtc_timer)
-		statclockintr(frame);
 	return (FILTER_HANDLED);
 }
 
@@ -146,8 +147,6 @@ int
 statclockintr(struct trapframe *frame)
 {
 
-	if (profprocs != 0)
-		profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	statclock(TRAPF_USERMODE(frame));
 	return (FILTER_HANDLED);
 }
@@ -193,6 +192,30 @@ clkintr(struct trapframe *frame)
 		ipi_all_but_self(IPI_HARDCLOCK);
 #endif 
 	hardclockintr(frame);
+
+	if (!using_atrtc_timer) {
+		prof_ticks += profhz;
+		if (prof_ticks >= hz) {
+			prof_ticks -= hz;
+			if (profprocs != 0) {
+#ifdef SMP
+				if (smp_started)
+					ipi_all_but_self(IPI_PROFCLOCK);
+#endif
+				profclockintr(frame);
+			}
+		}
+		stat_ticks += stathz;
+		if (stat_ticks >= hz) {
+			stat_ticks -= hz;
+#ifdef SMP
+			if (smp_started)
+				ipi_all_but_self(IPI_STATCLOCK);
+#endif
+			statclockintr(frame);
+		}
+	}
+
 #ifdef DEV_MCA
 	/* Reset clock interrupt by asserting bit 7 of port 0x61 */
 	if (MCA_system)
@@ -549,7 +572,8 @@ cpu_initclocks()
 			    INTR_TYPE_CLK, NULL);
 			atrtc_enable_intr();
 		} else {
-			profhz = stathz = hz;
+			profhz = min(RTC_PROFRATE, hz);
+			stathz = min(RTC_NOPROFRATE, hz);
 		}
 	}
 
@@ -560,7 +584,7 @@ void
 cpu_startprofclock(void)
 {
 
-	if (using_lapic_timer)
+	if (using_lapic_timer || !using_atrtc_timer)
 		return;
 	atrtc_rate(RTCSA_PROF);
 	psdiv = pscnt = psratio;
@@ -570,7 +594,7 @@ void
 cpu_stopprofclock(void)
 {
 
-	if (using_lapic_timer)
+	if (using_lapic_timer || !using_atrtc_timer)
 		return;
 	atrtc_rate(RTCSA_NOPROF);
 	psdiv = pscnt = 1;


More information about the svn-src-head mailing list