diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2018-10-26 18:06:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-26 19:26:32 -0400 |
commit | 5c54f5b9edb1aa2eabbb1091c458f1b6776a1896 (patch) | |
tree | 6111e4956d1aad00ae8cb8ba966aa87f41c79d55 | |
parent | 8508cf3ffad4defa202b303e5b6379efc4cd9054 (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.h | 3 | ||||
-rw-r--r-- | kernel/sched/loadavg.c | 138 |
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 | ||
40 | extern 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 | */ | ||
109 | static unsigned long | ||
110 | fixed_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 | */ | ||
156 | unsigned long | ||
157 | calc_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 | */ | ||
228 | static unsigned long | ||
229 | fixed_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 | */ | ||
275 | static unsigned long | ||
276 | calc_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 |