From 6026c54d859820652639d22385e89f06d26a3437 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 2 Aug 2012 17:26:30 +0800 Subject: [PATCH] statclock: Fix intr% counting on heavily interrupted systems 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 | 3 ++- sys/cpu/x86_64/include/cpu.h | 3 ++- sys/kern/kern_clock.c | 12 +++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/cpu/i386/include/cpu.h b/sys/cpu/i386/include/cpu.h index 485bd18..761375a 100644 --- a/sys/cpu/i386/include/cpu.h +++ b/sys/cpu/i386/include/cpu.h @@ -63,7 +63,8 @@ #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) /* diff --git a/sys/cpu/x86_64/include/cpu.h b/sys/cpu/x86_64/include/cpu.h index 7cd162c..293113f 100644 --- a/sys/cpu/x86_64/include/cpu.h +++ b/sys/cpu/x86_64/include/cpu.h @@ -63,7 +63,8 @@ #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) /* diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index a581a49..1933d0a 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -665,6 +665,9 @@ statclock(systimer_t info, int in_ipi, struct intrframe *frame) } } #endif + +#define IS_INTR_RUNNING ((frame && CLKF_INTR(intr_nest)) || CLKF_INTR_TD(td)) + /* * 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(). */ - if (frame && CLKF_INTR(intr_nest)) + if (IS_INTR_RUNNING) td->td_iticks += bump; else td->td_sticks += bump; - if (frame && CLKF_INTR(intr_nest)) { + if (IS_INTR_RUNNING) { #ifdef DEBUG_PCTRACK - do_pctrack(frame, PCTRACK_INT); + if (frame) + do_pctrack(frame, PCTRACK_INT); #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; } } + +#undef IS_INTR_RUNNING } } -- 1.7.7.2