statclock: Fix intr% counting on heavily interrupted systems
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 2 Aug 2012 09:26:30 +0000 (17:26 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 2 Aug 2012 09:26:30 +0000 (17:26 +0800)
statclock() has high probability to run from crit_exit() on heavily
interrupted systems and 'frame' is NULL in this case, so intr% is
mis-counted as sys%.

To fix this, TDF_INTTHREAD is used to determine whether intr% should
be counted or not, in addition to testing gd_intr_nest_level and
'frame'

sys/cpu/i386/include/cpu.h
sys/cpu/x86_64/include/cpu.h
sys/kern/kern_clock.c

index 485bd18..761375a 100644 (file)
@@ -63,7 +63,8 @@
 #define cpu_swapin(p)  /* nothing */
 #define cpu_setstack(lp, ap)           ((lp)->lwp_md.md_regs[SP] = (ap))
 
 #define cpu_swapin(p)  /* nothing */
 #define cpu_setstack(lp, ap)           ((lp)->lwp_md.md_regs[SP] = (ap))
 
-#define CLKF_INTR(intr_nest)   ((intr_nest) > 1 || (curthread->td_flags & TDF_INTTHREAD))
+#define CLKF_INTR(intr_nest)   ((intr_nest) > 1)
+#define CLKF_INTR_TD(td)       ((td)->td_flags & TDF_INTTHREAD)
 #define        CLKF_PC(framep)         ((framep)->if_eip)
 
 /*
 #define        CLKF_PC(framep)         ((framep)->if_eip)
 
 /*
index 7cd162c..293113f 100644 (file)
@@ -63,7 +63,8 @@
 #define cpu_swapin(p)  /* nothing */
 #define cpu_setstack(lp, ap)           ((lp)->lwp_md.md_regs[SP] = (ap))
 
 #define cpu_swapin(p)  /* nothing */
 #define cpu_setstack(lp, ap)           ((lp)->lwp_md.md_regs[SP] = (ap))
 
-#define CLKF_INTR(intr_nest)   ((intr_nest) > 1 || (curthread->td_flags & TDF_INTTHREAD))
+#define CLKF_INTR(intr_nest)   ((intr_nest) > 1)
+#define CLKF_INTR_TD(td)       ((td)->td_flags & TDF_INTTHREAD)
 #define        CLKF_PC(framep)         ((framep)->if_rip)
 
 /*
 #define        CLKF_PC(framep)         ((framep)->if_rip)
 
 /*
index a581a49..1933d0a 100644 (file)
@@ -665,6 +665,9 @@ statclock(systimer_t info, int in_ipi, struct intrframe *frame)
                        }
                }
 #endif
                        }
                }
 #endif
+
+#define IS_INTR_RUNNING        ((frame && CLKF_INTR(intr_nest)) || CLKF_INTR_TD(td))
+
                /*
                 * Came from kernel mode, so we were:
                 * - handling an interrupt,
                /*
                 * Came from kernel mode, so we were:
                 * - handling an interrupt,
@@ -680,14 +683,15 @@ statclock(systimer_t info, int in_ipi, struct intrframe *frame)
                 * XXX assume system if frame is NULL.  A NULL frame 
                 * can occur if ipi processing is done from a crit_exit().
                 */
                 * XXX assume system if frame is NULL.  A NULL frame 
                 * can occur if ipi processing is done from a crit_exit().
                 */
-               if (frame && CLKF_INTR(intr_nest))
+               if (IS_INTR_RUNNING)
                        td->td_iticks += bump;
                else
                        td->td_sticks += bump;
 
                        td->td_iticks += bump;
                else
                        td->td_sticks += bump;
 
-               if (frame && CLKF_INTR(intr_nest)) {
+               if (IS_INTR_RUNNING) {
 #ifdef DEBUG_PCTRACK
 #ifdef DEBUG_PCTRACK
-                       do_pctrack(frame, PCTRACK_INT);
+                       if (frame)
+                               do_pctrack(frame, PCTRACK_INT);
 #endif
                        cpu_time.cp_intr += bump;
                } else {
 #endif
                        cpu_time.cp_intr += bump;
                } else {
@@ -701,6 +705,8 @@ statclock(systimer_t info, int in_ipi, struct intrframe *frame)
                                cpu_time.cp_sys += bump;
                        }
                }
                                cpu_time.cp_sys += bump;
                        }
                }
+
+#undef IS_INTR_RUNNING
        }
 }
 
        }
 }