From 6e217da60df167fa6a2e07a9ee5b6015813bc89b Mon Sep 17 00:00:00 2001 From: Shawn Bohrer Date: Sat, 16 Feb 2013 21:22:23 -0600 Subject: [PATCH] Compute load in nanoseconds When computing the load_slice per irq we take the topology object load divided by the interrupt count for the object. Both of these values are integervalues which means if the interrupt count is larger than the load we get a load_slice of 0. It seems likely that on modern processors interrupt durations will be at least multiple nanoseconds long so if we compute load in nanoseconds it should be >= the interrupt count. The load is recomputed every SLEEP_INTERVAL which is currently 10s which makes the maximum possible load 10e9 which easily fits in a uint64_t. Note: corrected error checking on sysconf usage Signed-off-by: Shawn Bohrer Signed-off-by: Neil Horman --- constants.h | 2 ++ irqbalance.c | 7 +++++++ irqbalance.h | 1 + procinterrupts.c | 10 +++++----- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/constants.h b/constants.h index fe881bd..8e34339 100644 --- a/constants.h +++ b/constants.h @@ -4,6 +4,8 @@ /* interval between rebalance attempts in seconds */ #define SLEEP_INTERVAL 10 +#define NSEC_PER_SEC 1e9 + /* NUMA topology refresh intervals, in units of SLEEP_INTERVAL */ #define NUMA_REFRESH_INTERVAL 32 /* NIC interrupt refresh interval, in units of SLEEP_INTERVAL */ diff --git a/irqbalance.c b/irqbalance.c index b47db99..ca01719 100644 --- a/irqbalance.c +++ b/irqbalance.c @@ -54,6 +54,7 @@ unsigned long long cycle_count = 0; char *pidfile = NULL; char *banscript = NULL; char *polscript = NULL; +long HZ; void sleep_approx(int seconds) { @@ -274,6 +275,12 @@ int main(int argc, char** argv) log(TO_ALL, LOG_WARNING, "%s\n", note); } + HZ = sysconf(_SC_CLK_TCK); + if (HZ == -1) { + log(TO_ALL, LOG_WARNING, "Unable to determin HZ defaulting to 100\n"); + HZ = 100; + } + action.sa_handler = handler; sigemptyset(&action.sa_mask); action.sa_flags = 0; diff --git a/irqbalance.h b/irqbalance.h index 5d4843a..eef8a8a 100644 --- a/irqbalance.h +++ b/irqbalance.h @@ -70,6 +70,7 @@ extern char *banscript; extern char *polscript; extern cpumask_t banned_cpus; extern cpumask_t unbanned_cpus; +extern long HZ; /* * Numa node access routines diff --git a/procinterrupts.c b/procinterrupts.c index 2ba6f59..242a760 100644 --- a/procinterrupts.c +++ b/procinterrupts.c @@ -243,12 +243,12 @@ void parse_proc_stat(void) if (cycle_count) { cpu->load = (irq_load + softirq_load) - (cpu->last_load); /* - * the [soft]irq_load values are in jiffies, which are - * units of 10ms, multiply by 1000 to convert that to - * 1/10 milliseconds. This give us a better integer - * distribution of load between irqs + * the [soft]irq_load values are in jiffies, with + * HZ jiffies per second. Convert the load to nanoseconds + * to get a better integer resolution of nanoseconds per + * interrupt. */ - cpu->load *= 1000; + cpu->load *= NSEC_PER_SEC/HZ; } cpu->last_load = (irq_load + softirq_load); }