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);
                }
        }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to