summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2018-10-26 18:06:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-26 19:26:32 -0400
commit5c54f5b9edb1aa2eabbb1091c458f1b6776a1896 (patch)
tree6111e4956d1aad00ae8cb8ba966aa87f41c79d55
parent8508cf3ffad4defa202b303e5b6379efc4cd9054 (diff)
sched: loadavg: make calc_load_n() public
It's going to be used in a later patch. Keep the churn separate. Link: http://lkml.kernel.org/r/20180828172258.3185-6-hannes@cmpxchg.org Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Suren Baghdasaryan <surenb@google.com> Tested-by: Daniel Drake <drake@endlessm.com> Cc: Christopher Lameter <cl@linux.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Johannes Weiner <jweiner@fb.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Enderborg <peter.enderborg@sony.com> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Shakeel Butt <shakeelb@google.com> Cc: Tejun Heo <tj@kernel.org> Cc: Vinayak Menon <vinmenon@codeaurora.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/sched/loadavg.h3
-rw-r--r--kernel/sched/loadavg.c138
2 files changed, 72 insertions, 69 deletions
diff --git a/include/linux/sched/loadavg.h b/include/linux/sched/loadavg.h
index cc9cc62bb1f8..4859bea47a7b 100644
--- a/include/linux/sched/loadavg.h
+++ b/include/linux/sched/loadavg.h
@@ -37,6 +37,9 @@ calc_load(unsigned long load, unsigned long exp, unsigned long active)
37 return newload / FIXED_1; 37 return newload / FIXED_1;
38} 38}
39 39
40extern unsigned long calc_load_n(unsigned long load, unsigned long exp,
41 unsigned long active, unsigned int n);
42
40#define LOAD_INT(x) ((x) >> FSHIFT) 43#define LOAD_INT(x) ((x) >> FSHIFT)
41#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) 44#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
42 45
diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c
index 54fbdfb2d86c..28a516575c18 100644
--- a/kernel/sched/loadavg.c
+++ b/kernel/sched/loadavg.c
@@ -91,6 +91,75 @@ long calc_load_fold_active(struct rq *this_rq, long adjust)
91 return delta; 91 return delta;
92} 92}
93 93
94/**
95 * fixed_power_int - compute: x^n, in O(log n) time
96 *
97 * @x: base of the power
98 * @frac_bits: fractional bits of @x
99 * @n: power to raise @x to.
100 *
101 * By exploiting the relation between the definition of the natural power
102 * function: x^n := x*x*...*x (x multiplied by itself for n times), and
103 * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i,
104 * (where: n_i \elem {0, 1}, the binary vector representing n),
105 * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is
106 * of course trivially computable in O(log_2 n), the length of our binary
107 * vector.
108 */
109static unsigned long
110fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n)
111{
112 unsigned long result = 1UL << frac_bits;
113
114 if (n) {
115 for (;;) {
116 if (n & 1) {
117 result *= x;
118 result += 1UL << (frac_bits - 1);
119 result >>= frac_bits;
120 }
121 n >>= 1;
122 if (!n)
123 break;
124 x *= x;
125 x += 1UL << (frac_bits - 1);
126 x >>= frac_bits;
127 }
128 }
129
130 return result;
131}
132
133/*
134 * a1 = a0 * e + a * (1 - e)
135 *
136 * a2 = a1 * e + a * (1 - e)
137 * = (a0 * e + a * (1 - e)) * e + a * (1 - e)
138 * = a0 * e^2 + a * (1 - e) * (1 + e)
139 *
140 * a3 = a2 * e + a * (1 - e)
141 * = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e)
142 * = a0 * e^3 + a * (1 - e) * (1 + e + e^2)
143 *
144 * ...
145 *
146 * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1]
147 * = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e)
148 * = a0 * e^n + a * (1 - e^n)
149 *
150 * [1] application of the geometric series:
151 *
152 * n 1 - x^(n+1)
153 * S_n := \Sum x^i = -------------
154 * i=0 1 - x
155 */
156unsigned long
157calc_load_n(unsigned long load, unsigned long exp,
158 unsigned long active, unsigned int n)
159{
160 return calc_load(load, fixed_power_int(exp, FSHIFT, n), active);
161}
162
94#ifdef CONFIG_NO_HZ_COMMON 163#ifdef CONFIG_NO_HZ_COMMON
95/* 164/*
96 * Handle NO_HZ for the global load-average. 165 * Handle NO_HZ for the global load-average.
@@ -210,75 +279,6 @@ static long calc_load_nohz_fold(void)
210 return delta; 279 return delta;
211} 280}
212 281
213/**
214 * fixed_power_int - compute: x^n, in O(log n) time
215 *
216 * @x: base of the power
217 * @frac_bits: fractional bits of @x
218 * @n: power to raise @x to.
219 *
220 * By exploiting the relation between the definition of the natural power
221 * function: x^n := x*x*...*x (x multiplied by itself for n times), and
222 * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i,
223 * (where: n_i \elem {0, 1}, the binary vector representing n),
224 * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is
225 * of course trivially computable in O(log_2 n), the length of our binary
226 * vector.
227 */
228static unsigned long
229fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n)
230{
231 unsigned long result = 1UL << frac_bits;
232
233 if (n) {
234 for (;;) {
235 if (n & 1) {
236 result *= x;
237 result += 1UL << (frac_bits - 1);
238 result >>= frac_bits;
239 }
240 n >>= 1;
241 if (!n)
242 break;
243 x *= x;
244 x += 1UL << (frac_bits - 1);
245 x >>= frac_bits;
246 }
247 }
248
249 return result;
250}
251
252/*
253 * a1 = a0 * e + a * (1 - e)
254 *
255 * a2 = a1 * e + a * (1 - e)
256 * = (a0 * e + a * (1 - e)) * e + a * (1 - e)
257 * = a0 * e^2 + a * (1 - e) * (1 + e)
258 *
259 * a3 = a2 * e + a * (1 - e)
260 * = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e)
261 * = a0 * e^3 + a * (1 - e) * (1 + e + e^2)
262 *
263 * ...
264 *
265 * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1]
266 * = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e)
267 * = a0 * e^n + a * (1 - e^n)
268 *
269 * [1] application of the geometric series:
270 *
271 * n 1 - x^(n+1)
272 * S_n := \Sum x^i = -------------
273 * i=0 1 - x
274 */
275static unsigned long
276calc_load_n(unsigned long load, unsigned long exp,
277 unsigned long active, unsigned int n)
278{
279 return calc_load(load, fixed_power_int(exp, FSHIFT, n), active);
280}
281
282/* 282/*
283 * NO_HZ can leave us missing all per-CPU ticks calling 283 * NO_HZ can leave us missing all per-CPU ticks calling
284 * calc_load_fold_active(), but since a NO_HZ CPU folds its delta into 284 * calc_load_fold_active(), but since a NO_HZ CPU folds its delta into