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

Alexander Motin mav at FreeBSD.org
Tue Jun 23 21:45:34 UTC 2009


Author: mav
Date: Tue Jun 23 21:45:33 2009
New Revision: 194772
URL: http://svn.freebsd.org/changeset/base/194772

Log:
  Rework r193814:
  While general idea of patch was good, it was not working properly due the way
  it was implemented. When we are using same timer interrupt for several of
  hard/prof/stat purposes we should not send several IPIs same time to other
  CPUs. Sending several IPIs same time leads to terrible accounting/profiling
  results due to strong synchronization effect, when the second interrupt
  handler accounts processing of the first one.
  Interlink timer events in a such way, that no more then one IPI is sent for
  any original timer interrupt.

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 23 21:43:02 2009	(r194771)
+++ head/sys/amd64/isa/clock.c	Tue Jun 23 21:45:33 2009	(r194772)
@@ -93,9 +93,6 @@ 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
@@ -132,6 +129,7 @@ int
 statclockintr(struct trapframe *frame)
 {
 
+	profclockintr(frame);
 	statclock(TRAPF_USERMODE(frame));
 	return (FILTER_HANDLED);
 }
@@ -140,7 +138,10 @@ int
 profclockintr(struct trapframe *frame)
 {
 
-	profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	if (!using_atrtc_timer)
+		hardclockintr(frame);
+	if (profprocs != 0)
+		profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	return (FILTER_HANDLED);
 }
 
@@ -160,32 +161,27 @@ clkintr(struct trapframe *frame)
 		mtx_unlock_spin(&clock_lock);
 	}
 	KASSERT(!using_lapic_timer, ("clk interrupt enabled with lapic timer"));
-#ifdef SMP
-	if (smp_started)
-		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) {
+	if (using_atrtc_timer) {
 #ifdef SMP
-				if (smp_started)
-					ipi_all_but_self(IPI_PROFCLOCK);
+		if (smp_started)
+			ipi_all_but_self(IPI_HARDCLOCK);
 #endif
-				profclockintr(frame);
-			}
-		}
-		stat_ticks += stathz;
-		if (stat_ticks >= hz) {
-			stat_ticks -= hz;
+		hardclockintr(frame);
+	} else {
+		if (--pscnt == 0) {
+			pscnt = psrate;
 #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);
+#endif
+			profclockintr(frame);
 		}
 	}
 
@@ -266,21 +262,19 @@ rtcintr(struct trapframe *frame)
 
 	while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
 		flag = 1;
-		if (profprocs != 0) {
-			if (--pscnt == 0)
-				pscnt = psdiv;
+		if (--pscnt == 0) {
+			pscnt = psdiv;
 #ifdef SMP
-			if (pscnt != psdiv && smp_started)
-				ipi_all_but_self(IPI_PROFCLOCK);
+			if (smp_started)
+				ipi_all_but_self(IPI_STATCLOCK);
 #endif
-			profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-		}
-		if (pscnt == psdiv) {
+			statclockintr(frame);
+		} else {
 #ifdef SMP
 			if (smp_started)
-				ipi_all_but_self(IPI_STATCLOCK);
+				ipi_all_but_self(IPI_PROFCLOCK);
 #endif
-			statclock(TRAPF_USERMODE(frame));
+			profclockintr(frame);
 		}
 	}
 	return(flag ? FILTER_HANDLED : FILTER_STRAY);
@@ -523,8 +517,11 @@ cpu_initclocks()
 			    INTR_TYPE_CLK, NULL);
 			atrtc_enable_intr();
 		} else {
-			profhz = min(RTC_PROFRATE, hz);
-			stathz = min(RTC_NOPROFRATE, hz);
+			profhz = hz;
+			if (hz < 128)
+				stathz = hz;
+			else
+				stathz = hz / (hz / 128);
 		}
 	}
 

Modified: head/sys/i386/isa/clock.c
==============================================================================
--- head/sys/i386/isa/clock.c	Tue Jun 23 21:43:02 2009	(r194771)
+++ head/sys/i386/isa/clock.c	Tue Jun 23 21:45:33 2009	(r194772)
@@ -108,9 +108,6 @@ 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
@@ -147,6 +144,7 @@ int
 statclockintr(struct trapframe *frame)
 {
 
+	profclockintr(frame);
 	statclock(TRAPF_USERMODE(frame));
 	return (FILTER_HANDLED);
 }
@@ -155,7 +153,10 @@ int
 profclockintr(struct trapframe *frame)
 {
 
-	profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	if (!using_atrtc_timer)
+		hardclockintr(frame);
+	if (profprocs != 0)
+		profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	return (FILTER_HANDLED);
 }
 
@@ -187,32 +188,26 @@ clkintr(struct trapframe *frame)
 		(*lapic_cyclic_clock_func[cpu])(frame);
 #endif
 
+	if (using_atrtc_timer) {
 #ifdef SMP
-	if (smp_started)
-		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);
+		if (smp_started)
+			ipi_all_but_self(IPI_HARDCLOCK);
 #endif
-				profclockintr(frame);
-			}
-		}
-		stat_ticks += stathz;
-		if (stat_ticks >= hz) {
-			stat_ticks -= hz;
+		hardclockintr(frame);
+	} else {
+		if (--pscnt == 0) {
+			pscnt = psratio;
 #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);
+#endif
+			profclockintr(frame);
 		}
 	}
 
@@ -298,21 +293,19 @@ rtcintr(struct trapframe *frame)
 
 	while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
 		flag = 1;
-		if (profprocs != 0) {
-			if (--pscnt == 0)
-				pscnt = psdiv;
+		if (--pscnt == 0) {
+			pscnt = psdiv;
 #ifdef SMP
-			if (pscnt != psdiv && smp_started)
-				ipi_all_but_self(IPI_PROFCLOCK);
+			if (smp_started)
+				ipi_all_but_self(IPI_STATCLOCK);
 #endif
-			profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-		}
-		if (pscnt == psdiv) {
+			statclockintr(frame);
+		} else {
 #ifdef SMP
-			if (smp_started) 
-				ipi_all_but_self(IPI_STATCLOCK); 
+			if (smp_started)
+				ipi_all_but_self(IPI_PROFCLOCK);
 #endif
-			statclock(TRAPF_USERMODE(frame));
+			profclockintr(frame);
 		}
 	}
 	return(flag ? FILTER_HANDLED : FILTER_STRAY);
@@ -572,8 +565,11 @@ cpu_initclocks()
 			    INTR_TYPE_CLK, NULL);
 			atrtc_enable_intr();
 		} else {
-			profhz = min(RTC_PROFRATE, hz);
-			stathz = min(RTC_NOPROFRATE, hz);
+			profhz = hz;
+			if (hz < 128)
+				stathz = hz;
+			else
+				stathz = hz / (hz / 128);
 		}
 	}
 


More information about the svn-src-head mailing list