Skip to content

Instantly share code, notes, and snippets.

@AndreiLux
Created April 18, 2013 10:46
Show Gist options
  • Save AndreiLux/5411832 to your computer and use it in GitHub Desktop.
Save AndreiLux/5411832 to your computer and use it in GitHub Desktop.
From b0b330221c9d7a339bf71f2ceb4859f71fd7ea9d Mon Sep 17 00:00:00 2001
From: Andrei F <luxneb@gmail.com>
Date: Sat, 12 Nov 2011 15:38:00 +0100
Subject: [PATCH] sched: Fix loadavg calculations
This includes the alteration of the load calculation frequency
by Klaus Ripke <klaus@ripke.com> "LOAD_FREQ (4*HZ+61) avoids loadavg Moire"
http://ripke.com/loadavg/moire
But correctly alters the timings for 200 HZ devices as in the mobile
space, the original patch is meant for 100 HZ kernels on x86 and other archs.
Furthermore, the exponential constants are completely wrong for the same
reason, they were caluclated and hardcoded for 100 HZ.
From https://lkml.org/lkml/2013/2/1/93 , the exponential math is taken
to fully expand the macro behind those values and to be truly HZ independent.
The 64bit-ness of the above patch is avoided for our ARM purposes.
---
include/linux/sched.h | 13 +++++++------
kernel/sched.c | 10 +++++-----
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f19df63..74cb8b3 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -120,12 +120,13 @@ struct blk_plug;
extern unsigned long avenrun[]; /* Load averages */
extern void get_avenrun(unsigned long *loads, unsigned long offset, int shift);
-#define FSHIFT 11 /* nr of bits of precision */
-#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
-#define LOAD_FREQ (5*HZ+1) /* 5 sec intervals */
-#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
-#define EXP_5 2014 /* 1/exp(5sec/5min) */
-#define EXP_15 2037 /* 1/exp(5sec/15min) */
+#define FSHIFT 11 /* bits of precision */
+#define LOAD_FREQ (4*HZ+122) /* 4.61 sec intervals */
+
+#define FIXED_1 (1UL<<FSHIFT) /* 1.0 as fixed-point */
+#define EXP_1 (FIXED_1-((FIXED_1*LOAD_FREQ)/(HZ*1*60UL)))
+#define EXP_5 (FIXED_1-((FIXED_1*LOAD_FREQ)/(HZ*5*60UL)))
+#define EXP_15 (FIXED_1-((FIXED_1*LOAD_FREQ)/(HZ*15*60UL)))
#define CALC_LOAD(load,exp,n) \
load *= exp; \
diff --git a/kernel/sched.c b/kernel/sched.c
index fc37d84..987513f 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3565,7 +3565,7 @@ static inline int calc_load_write_idx(void)
* If the folding window started, make sure we start writing in the
* next idle-delta.
*/
- if (!time_before(jiffies, calc_load_update))
+ if (!time_before_eq(jiffies, calc_load_update))
idx++;
return idx & 1;
@@ -3607,7 +3607,7 @@ void calc_load_exit_idle(void)
/*
* If we're still before the sample window, we're done.
*/
- if (time_before(jiffies, this_rq->calc_load_update))
+ if (time_before_eq(jiffies, this_rq->calc_load_update))
return;
/*
@@ -3727,7 +3727,7 @@ static void calc_global_nohz(void)
{
long delta, active, n;
- if (!time_before(jiffies, calc_load_update + 10)) {
+ if (!time_before_eq(jiffies, calc_load_update + 10)) {
/*
* Catch-up, fold however many we are behind still
*/
@@ -3770,7 +3770,7 @@ void calc_global_load(unsigned long ticks)
{
long active, delta;
- if (time_before(jiffies, calc_load_update + 10))
+ if (time_before_eq(jiffies, calc_load_update + 10))
return;
/*
@@ -3823,7 +3823,7 @@ static void calc_load_account_active(struct rq *this_rq)
{
long delta;
- if (time_before(jiffies, this_rq->calc_load_update))
+ if (time_before_eq(jiffies, this_rq->calc_load_update))
return;
delta = calc_load_fold_active(this_rq);
--
1.7.5.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment