1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
23289bdb4SPeter Zijlstra /*
33289bdb4SPeter Zijlstra * kernel/sched/loadavg.c
43289bdb4SPeter Zijlstra *
53289bdb4SPeter Zijlstra * This file contains the magic bits required to compute the global loadavg
63289bdb4SPeter Zijlstra * figure. Its a silly number but people think its important. We go through
73289bdb4SPeter Zijlstra * great pains to make it work on big machines and tickless kernels.
83289bdb4SPeter Zijlstra */
93289bdb4SPeter Zijlstra
103289bdb4SPeter Zijlstra /*
113289bdb4SPeter Zijlstra * Global load-average calculations
123289bdb4SPeter Zijlstra *
133289bdb4SPeter Zijlstra * We take a distributed and async approach to calculating the global load-avg
143289bdb4SPeter Zijlstra * in order to minimize overhead.
153289bdb4SPeter Zijlstra *
163289bdb4SPeter Zijlstra * The global load average is an exponentially decaying average of nr_running +
173289bdb4SPeter Zijlstra * nr_uninterruptible.
183289bdb4SPeter Zijlstra *
193289bdb4SPeter Zijlstra * Once every LOAD_FREQ:
203289bdb4SPeter Zijlstra *
213289bdb4SPeter Zijlstra * nr_active = 0;
223289bdb4SPeter Zijlstra * for_each_possible_cpu(cpu)
233289bdb4SPeter Zijlstra * nr_active += cpu_of(cpu)->nr_running + cpu_of(cpu)->nr_uninterruptible;
243289bdb4SPeter Zijlstra *
253289bdb4SPeter Zijlstra * avenrun[n] = avenrun[0] * exp_n + nr_active * (1 - exp_n)
263289bdb4SPeter Zijlstra *
273289bdb4SPeter Zijlstra * Due to a number of reasons the above turns in the mess below:
283289bdb4SPeter Zijlstra *
293289bdb4SPeter Zijlstra * - for_each_possible_cpu() is prohibitively expensive on machines with
3097fb7a0aSIngo Molnar * serious number of CPUs, therefore we need to take a distributed approach
313289bdb4SPeter Zijlstra * to calculating nr_active.
323289bdb4SPeter Zijlstra *
333289bdb4SPeter Zijlstra * \Sum_i x_i(t) = \Sum_i x_i(t) - x_i(t_0) | x_i(t_0) := 0
343289bdb4SPeter Zijlstra * = \Sum_i { \Sum_j=1 x_i(t_j) - x_i(t_j-1) }
353289bdb4SPeter Zijlstra *
363289bdb4SPeter Zijlstra * So assuming nr_active := 0 when we start out -- true per definition, we
3797fb7a0aSIngo Molnar * can simply take per-CPU deltas and fold those into a global accumulate
383289bdb4SPeter Zijlstra * to obtain the same result. See calc_load_fold_active().
393289bdb4SPeter Zijlstra *
4097fb7a0aSIngo Molnar * Furthermore, in order to avoid synchronizing all per-CPU delta folding
413289bdb4SPeter Zijlstra * across the machine, we assume 10 ticks is sufficient time for every
4297fb7a0aSIngo Molnar * CPU to have completed this task.
433289bdb4SPeter Zijlstra *
443289bdb4SPeter Zijlstra * This places an upper-bound on the IRQ-off latency of the machine. Then
453289bdb4SPeter Zijlstra * again, being late doesn't loose the delta, just wrecks the sample.
463289bdb4SPeter Zijlstra *
4797fb7a0aSIngo Molnar * - cpu_rq()->nr_uninterruptible isn't accurately tracked per-CPU because
4897fb7a0aSIngo Molnar * this would add another cross-CPU cacheline miss and atomic operation
4997fb7a0aSIngo Molnar * to the wakeup path. Instead we increment on whatever CPU the task ran
5097fb7a0aSIngo Molnar * when it went into uninterruptible state and decrement on whatever CPU
513289bdb4SPeter Zijlstra * did the wakeup. This means that only the sum of nr_uninterruptible over
5297fb7a0aSIngo Molnar * all CPUs yields the correct result.
533289bdb4SPeter Zijlstra *
543289bdb4SPeter Zijlstra * This covers the NO_HZ=n code, for extra head-aches, see the comment below.
553289bdb4SPeter Zijlstra */
563289bdb4SPeter Zijlstra
573289bdb4SPeter Zijlstra /* Variables and functions for calc_load */
583289bdb4SPeter Zijlstra atomic_long_t calc_load_tasks;
593289bdb4SPeter Zijlstra unsigned long calc_load_update;
603289bdb4SPeter Zijlstra unsigned long avenrun[3];
613289bdb4SPeter Zijlstra EXPORT_SYMBOL(avenrun); /* should be removed */
623289bdb4SPeter Zijlstra
633289bdb4SPeter Zijlstra /**
643289bdb4SPeter Zijlstra * get_avenrun - get the load average array
653289bdb4SPeter Zijlstra * @loads: pointer to dest load array
663289bdb4SPeter Zijlstra * @offset: offset to add
673289bdb4SPeter Zijlstra * @shift: shift count to shift the result left
683289bdb4SPeter Zijlstra *
693289bdb4SPeter Zijlstra * These values are estimates at best, so no need for locking.
703289bdb4SPeter Zijlstra */
get_avenrun(unsigned long * loads,unsigned long offset,int shift)713289bdb4SPeter Zijlstra void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
723289bdb4SPeter Zijlstra {
733289bdb4SPeter Zijlstra loads[0] = (avenrun[0] + offset) << shift;
743289bdb4SPeter Zijlstra loads[1] = (avenrun[1] + offset) << shift;
753289bdb4SPeter Zijlstra loads[2] = (avenrun[2] + offset) << shift;
763289bdb4SPeter Zijlstra }
773289bdb4SPeter Zijlstra
calc_load_fold_active(struct rq * this_rq,long adjust)78d60585c5SThomas Gleixner long calc_load_fold_active(struct rq *this_rq, long adjust)
793289bdb4SPeter Zijlstra {
803289bdb4SPeter Zijlstra long nr_active, delta = 0;
813289bdb4SPeter Zijlstra
82d60585c5SThomas Gleixner nr_active = this_rq->nr_running - adjust;
83*e6fe3f42SAlexey Dobriyan nr_active += (int)this_rq->nr_uninterruptible;
843289bdb4SPeter Zijlstra
853289bdb4SPeter Zijlstra if (nr_active != this_rq->calc_load_active) {
863289bdb4SPeter Zijlstra delta = nr_active - this_rq->calc_load_active;
873289bdb4SPeter Zijlstra this_rq->calc_load_active = nr_active;
883289bdb4SPeter Zijlstra }
893289bdb4SPeter Zijlstra
903289bdb4SPeter Zijlstra return delta;
913289bdb4SPeter Zijlstra }
923289bdb4SPeter Zijlstra
935c54f5b9SJohannes Weiner /**
945c54f5b9SJohannes Weiner * fixed_power_int - compute: x^n, in O(log n) time
955c54f5b9SJohannes Weiner *
965c54f5b9SJohannes Weiner * @x: base of the power
975c54f5b9SJohannes Weiner * @frac_bits: fractional bits of @x
985c54f5b9SJohannes Weiner * @n: power to raise @x to.
995c54f5b9SJohannes Weiner *
1005c54f5b9SJohannes Weiner * By exploiting the relation between the definition of the natural power
1015c54f5b9SJohannes Weiner * function: x^n := x*x*...*x (x multiplied by itself for n times), and
1025c54f5b9SJohannes Weiner * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i,
1035c54f5b9SJohannes Weiner * (where: n_i \elem {0, 1}, the binary vector representing n),
1045c54f5b9SJohannes Weiner * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is
1055c54f5b9SJohannes Weiner * of course trivially computable in O(log_2 n), the length of our binary
1065c54f5b9SJohannes Weiner * vector.
1075c54f5b9SJohannes Weiner */
1085c54f5b9SJohannes Weiner static unsigned long
fixed_power_int(unsigned long x,unsigned int frac_bits,unsigned int n)1095c54f5b9SJohannes Weiner fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n)
1105c54f5b9SJohannes Weiner {
1115c54f5b9SJohannes Weiner unsigned long result = 1UL << frac_bits;
1125c54f5b9SJohannes Weiner
1135c54f5b9SJohannes Weiner if (n) {
1145c54f5b9SJohannes Weiner for (;;) {
1155c54f5b9SJohannes Weiner if (n & 1) {
1165c54f5b9SJohannes Weiner result *= x;
1175c54f5b9SJohannes Weiner result += 1UL << (frac_bits - 1);
1185c54f5b9SJohannes Weiner result >>= frac_bits;
1195c54f5b9SJohannes Weiner }
1205c54f5b9SJohannes Weiner n >>= 1;
1215c54f5b9SJohannes Weiner if (!n)
1225c54f5b9SJohannes Weiner break;
1235c54f5b9SJohannes Weiner x *= x;
1245c54f5b9SJohannes Weiner x += 1UL << (frac_bits - 1);
1255c54f5b9SJohannes Weiner x >>= frac_bits;
1265c54f5b9SJohannes Weiner }
1275c54f5b9SJohannes Weiner }
1285c54f5b9SJohannes Weiner
1295c54f5b9SJohannes Weiner return result;
1305c54f5b9SJohannes Weiner }
1315c54f5b9SJohannes Weiner
1325c54f5b9SJohannes Weiner /*
1335c54f5b9SJohannes Weiner * a1 = a0 * e + a * (1 - e)
1345c54f5b9SJohannes Weiner *
1355c54f5b9SJohannes Weiner * a2 = a1 * e + a * (1 - e)
1365c54f5b9SJohannes Weiner * = (a0 * e + a * (1 - e)) * e + a * (1 - e)
1375c54f5b9SJohannes Weiner * = a0 * e^2 + a * (1 - e) * (1 + e)
1385c54f5b9SJohannes Weiner *
1395c54f5b9SJohannes Weiner * a3 = a2 * e + a * (1 - e)
1405c54f5b9SJohannes Weiner * = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e)
1415c54f5b9SJohannes Weiner * = a0 * e^3 + a * (1 - e) * (1 + e + e^2)
1425c54f5b9SJohannes Weiner *
1435c54f5b9SJohannes Weiner * ...
1445c54f5b9SJohannes Weiner *
1455c54f5b9SJohannes Weiner * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1]
1465c54f5b9SJohannes Weiner * = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e)
1475c54f5b9SJohannes Weiner * = a0 * e^n + a * (1 - e^n)
1485c54f5b9SJohannes Weiner *
1495c54f5b9SJohannes Weiner * [1] application of the geometric series:
1505c54f5b9SJohannes Weiner *
1515c54f5b9SJohannes Weiner * n 1 - x^(n+1)
1525c54f5b9SJohannes Weiner * S_n := \Sum x^i = -------------
1535c54f5b9SJohannes Weiner * i=0 1 - x
1545c54f5b9SJohannes Weiner */
1555c54f5b9SJohannes Weiner unsigned long
calc_load_n(unsigned long load,unsigned long exp,unsigned long active,unsigned int n)1565c54f5b9SJohannes Weiner calc_load_n(unsigned long load, unsigned long exp,
1575c54f5b9SJohannes Weiner unsigned long active, unsigned int n)
1585c54f5b9SJohannes Weiner {
1595c54f5b9SJohannes Weiner return calc_load(load, fixed_power_int(exp, FSHIFT, n), active);
1605c54f5b9SJohannes Weiner }
1615c54f5b9SJohannes Weiner
1623289bdb4SPeter Zijlstra #ifdef CONFIG_NO_HZ_COMMON
1633289bdb4SPeter Zijlstra /*
1643289bdb4SPeter Zijlstra * Handle NO_HZ for the global load-average.
1653289bdb4SPeter Zijlstra *
1663289bdb4SPeter Zijlstra * Since the above described distributed algorithm to compute the global
16797fb7a0aSIngo Molnar * load-average relies on per-CPU sampling from the tick, it is affected by
1683289bdb4SPeter Zijlstra * NO_HZ.
1693289bdb4SPeter Zijlstra *
1703c85d6dbSFrederic Weisbecker * The basic idea is to fold the nr_active delta into a global NO_HZ-delta upon
17197fb7a0aSIngo Molnar * entering NO_HZ state such that we can include this as an 'extra' CPU delta
1723289bdb4SPeter Zijlstra * when we read the global state.
1733289bdb4SPeter Zijlstra *
1743289bdb4SPeter Zijlstra * Obviously reality has to ruin such a delightfully simple scheme:
1753289bdb4SPeter Zijlstra *
1763289bdb4SPeter Zijlstra * - When we go NO_HZ idle during the window, we can negate our sample
1773289bdb4SPeter Zijlstra * contribution, causing under-accounting.
1783289bdb4SPeter Zijlstra *
1793c85d6dbSFrederic Weisbecker * We avoid this by keeping two NO_HZ-delta counters and flipping them
1803289bdb4SPeter Zijlstra * when the window starts, thus separating old and new NO_HZ load.
1813289bdb4SPeter Zijlstra *
1823289bdb4SPeter Zijlstra * The only trick is the slight shift in index flip for read vs write.
1833289bdb4SPeter Zijlstra *
1843289bdb4SPeter Zijlstra * 0s 5s 10s 15s
1853289bdb4SPeter Zijlstra * +10 +10 +10 +10
1863289bdb4SPeter Zijlstra * |-|-----------|-|-----------|-|-----------|-|
1873289bdb4SPeter Zijlstra * r:0 0 1 1 0 0 1 1 0
1883289bdb4SPeter Zijlstra * w:0 1 1 0 0 1 1 0 0
1893289bdb4SPeter Zijlstra *
1903c85d6dbSFrederic Weisbecker * This ensures we'll fold the old NO_HZ contribution in this window while
1913b03706fSIngo Molnar * accumulating the new one.
1923289bdb4SPeter Zijlstra *
1933c85d6dbSFrederic Weisbecker * - When we wake up from NO_HZ during the window, we push up our
1943289bdb4SPeter Zijlstra * contribution, since we effectively move our sample point to a known
1953289bdb4SPeter Zijlstra * busy state.
1963289bdb4SPeter Zijlstra *
1973289bdb4SPeter Zijlstra * This is solved by pushing the window forward, and thus skipping the
19897fb7a0aSIngo Molnar * sample, for this CPU (effectively using the NO_HZ-delta for this CPU which
1993289bdb4SPeter Zijlstra * was in effect at the time the window opened). This also solves the issue
20097fb7a0aSIngo Molnar * of having to deal with a CPU having been in NO_HZ for multiple LOAD_FREQ
2013c85d6dbSFrederic Weisbecker * intervals.
2023289bdb4SPeter Zijlstra *
2033289bdb4SPeter Zijlstra * When making the ILB scale, we should try to pull this in as well.
2043289bdb4SPeter Zijlstra */
2053c85d6dbSFrederic Weisbecker static atomic_long_t calc_load_nohz[2];
2063289bdb4SPeter Zijlstra static int calc_load_idx;
2073289bdb4SPeter Zijlstra
calc_load_write_idx(void)2083289bdb4SPeter Zijlstra static inline int calc_load_write_idx(void)
2093289bdb4SPeter Zijlstra {
2103289bdb4SPeter Zijlstra int idx = calc_load_idx;
2113289bdb4SPeter Zijlstra
2123289bdb4SPeter Zijlstra /*
2133289bdb4SPeter Zijlstra * See calc_global_nohz(), if we observe the new index, we also
2143289bdb4SPeter Zijlstra * need to observe the new update time.
2153289bdb4SPeter Zijlstra */
2163289bdb4SPeter Zijlstra smp_rmb();
2173289bdb4SPeter Zijlstra
2183289bdb4SPeter Zijlstra /*
2193289bdb4SPeter Zijlstra * If the folding window started, make sure we start writing in the
2203c85d6dbSFrederic Weisbecker * next NO_HZ-delta.
2213289bdb4SPeter Zijlstra */
222caeb5882SMatt Fleming if (!time_before(jiffies, READ_ONCE(calc_load_update)))
2233289bdb4SPeter Zijlstra idx++;
2243289bdb4SPeter Zijlstra
2253289bdb4SPeter Zijlstra return idx & 1;
2263289bdb4SPeter Zijlstra }
2273289bdb4SPeter Zijlstra
calc_load_read_idx(void)2283289bdb4SPeter Zijlstra static inline int calc_load_read_idx(void)
2293289bdb4SPeter Zijlstra {
2303289bdb4SPeter Zijlstra return calc_load_idx & 1;
2313289bdb4SPeter Zijlstra }
2323289bdb4SPeter Zijlstra
calc_load_nohz_fold(struct rq * rq)233ebc0f83cSPeter Zijlstra (Intel) static void calc_load_nohz_fold(struct rq *rq)
2343289bdb4SPeter Zijlstra {
2353289bdb4SPeter Zijlstra long delta;
2363289bdb4SPeter Zijlstra
237ebc0f83cSPeter Zijlstra (Intel) delta = calc_load_fold_active(rq, 0);
2383289bdb4SPeter Zijlstra if (delta) {
2393289bdb4SPeter Zijlstra int idx = calc_load_write_idx();
2403289bdb4SPeter Zijlstra
2413c85d6dbSFrederic Weisbecker atomic_long_add(delta, &calc_load_nohz[idx]);
2423289bdb4SPeter Zijlstra }
2433289bdb4SPeter Zijlstra }
2443289bdb4SPeter Zijlstra
calc_load_nohz_start(void)245ebc0f83cSPeter Zijlstra (Intel) void calc_load_nohz_start(void)
246ebc0f83cSPeter Zijlstra (Intel) {
247ebc0f83cSPeter Zijlstra (Intel) /*
248ebc0f83cSPeter Zijlstra (Intel) * We're going into NO_HZ mode, if there's any pending delta, fold it
249ebc0f83cSPeter Zijlstra (Intel) * into the pending NO_HZ delta.
250ebc0f83cSPeter Zijlstra (Intel) */
251ebc0f83cSPeter Zijlstra (Intel) calc_load_nohz_fold(this_rq());
252ebc0f83cSPeter Zijlstra (Intel) }
253ebc0f83cSPeter Zijlstra (Intel)
254ebc0f83cSPeter Zijlstra (Intel) /*
255ebc0f83cSPeter Zijlstra (Intel) * Keep track of the load for NOHZ_FULL, must be called between
256ebc0f83cSPeter Zijlstra (Intel) * calc_load_nohz_{start,stop}().
257ebc0f83cSPeter Zijlstra (Intel) */
calc_load_nohz_remote(struct rq * rq)258ebc0f83cSPeter Zijlstra (Intel) void calc_load_nohz_remote(struct rq *rq)
259ebc0f83cSPeter Zijlstra (Intel) {
260ebc0f83cSPeter Zijlstra (Intel) calc_load_nohz_fold(rq);
261ebc0f83cSPeter Zijlstra (Intel) }
262ebc0f83cSPeter Zijlstra (Intel)
calc_load_nohz_stop(void)2633c85d6dbSFrederic Weisbecker void calc_load_nohz_stop(void)
2643289bdb4SPeter Zijlstra {
2653289bdb4SPeter Zijlstra struct rq *this_rq = this_rq();
2663289bdb4SPeter Zijlstra
2673289bdb4SPeter Zijlstra /*
2686e5f32f7SMatt Fleming * If we're still before the pending sample window, we're done.
2693289bdb4SPeter Zijlstra */
270caeb5882SMatt Fleming this_rq->calc_load_update = READ_ONCE(calc_load_update);
2713289bdb4SPeter Zijlstra if (time_before(jiffies, this_rq->calc_load_update))
2723289bdb4SPeter Zijlstra return;
2733289bdb4SPeter Zijlstra
2743289bdb4SPeter Zijlstra /*
2753289bdb4SPeter Zijlstra * We woke inside or after the sample window, this means we're already
2763289bdb4SPeter Zijlstra * accounted through the nohz accounting, so skip the entire deal and
2773289bdb4SPeter Zijlstra * sync up for the next window.
2783289bdb4SPeter Zijlstra */
2793289bdb4SPeter Zijlstra if (time_before(jiffies, this_rq->calc_load_update + 10))
2803289bdb4SPeter Zijlstra this_rq->calc_load_update += LOAD_FREQ;
2813289bdb4SPeter Zijlstra }
2823289bdb4SPeter Zijlstra
calc_load_nohz_read(void)283ebc0f83cSPeter Zijlstra (Intel) static long calc_load_nohz_read(void)
2843289bdb4SPeter Zijlstra {
2853289bdb4SPeter Zijlstra int idx = calc_load_read_idx();
2863289bdb4SPeter Zijlstra long delta = 0;
2873289bdb4SPeter Zijlstra
2883c85d6dbSFrederic Weisbecker if (atomic_long_read(&calc_load_nohz[idx]))
2893c85d6dbSFrederic Weisbecker delta = atomic_long_xchg(&calc_load_nohz[idx], 0);
2903289bdb4SPeter Zijlstra
2913289bdb4SPeter Zijlstra return delta;
2923289bdb4SPeter Zijlstra }
2933289bdb4SPeter Zijlstra
2943289bdb4SPeter Zijlstra /*
29597fb7a0aSIngo Molnar * NO_HZ can leave us missing all per-CPU ticks calling
2963c85d6dbSFrederic Weisbecker * calc_load_fold_active(), but since a NO_HZ CPU folds its delta into
2973c85d6dbSFrederic Weisbecker * calc_load_nohz per calc_load_nohz_start(), all we need to do is fold
2983c85d6dbSFrederic Weisbecker * in the pending NO_HZ delta if our NO_HZ period crossed a load cycle boundary.
2993289bdb4SPeter Zijlstra *
3003289bdb4SPeter Zijlstra * Once we've updated the global active value, we need to apply the exponential
3013289bdb4SPeter Zijlstra * weights adjusted to the number of cycles missed.
3023289bdb4SPeter Zijlstra */
calc_global_nohz(void)3033289bdb4SPeter Zijlstra static void calc_global_nohz(void)
3043289bdb4SPeter Zijlstra {
305caeb5882SMatt Fleming unsigned long sample_window;
3063289bdb4SPeter Zijlstra long delta, active, n;
3073289bdb4SPeter Zijlstra
308caeb5882SMatt Fleming sample_window = READ_ONCE(calc_load_update);
309caeb5882SMatt Fleming if (!time_before(jiffies, sample_window + 10)) {
3103289bdb4SPeter Zijlstra /*
3113289bdb4SPeter Zijlstra * Catch-up, fold however many we are behind still
3123289bdb4SPeter Zijlstra */
313caeb5882SMatt Fleming delta = jiffies - sample_window - 10;
3143289bdb4SPeter Zijlstra n = 1 + (delta / LOAD_FREQ);
3153289bdb4SPeter Zijlstra
3163289bdb4SPeter Zijlstra active = atomic_long_read(&calc_load_tasks);
3173289bdb4SPeter Zijlstra active = active > 0 ? active * FIXED_1 : 0;
3183289bdb4SPeter Zijlstra
3193289bdb4SPeter Zijlstra avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
3203289bdb4SPeter Zijlstra avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
3213289bdb4SPeter Zijlstra avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
3223289bdb4SPeter Zijlstra
323caeb5882SMatt Fleming WRITE_ONCE(calc_load_update, sample_window + n * LOAD_FREQ);
3243289bdb4SPeter Zijlstra }
3253289bdb4SPeter Zijlstra
3263289bdb4SPeter Zijlstra /*
3273c85d6dbSFrederic Weisbecker * Flip the NO_HZ index...
3283289bdb4SPeter Zijlstra *
3293289bdb4SPeter Zijlstra * Make sure we first write the new time then flip the index, so that
3303289bdb4SPeter Zijlstra * calc_load_write_idx() will see the new time when it reads the new
3313289bdb4SPeter Zijlstra * index, this avoids a double flip messing things up.
3323289bdb4SPeter Zijlstra */
3333289bdb4SPeter Zijlstra smp_wmb();
3343289bdb4SPeter Zijlstra calc_load_idx++;
3353289bdb4SPeter Zijlstra }
3363289bdb4SPeter Zijlstra #else /* !CONFIG_NO_HZ_COMMON */
3373289bdb4SPeter Zijlstra
calc_load_nohz_read(void)338ebc0f83cSPeter Zijlstra (Intel) static inline long calc_load_nohz_read(void) { return 0; }
calc_global_nohz(void)3393289bdb4SPeter Zijlstra static inline void calc_global_nohz(void) { }
3403289bdb4SPeter Zijlstra
3413289bdb4SPeter Zijlstra #endif /* CONFIG_NO_HZ_COMMON */
3423289bdb4SPeter Zijlstra
3433289bdb4SPeter Zijlstra /*
3443289bdb4SPeter Zijlstra * calc_load - update the avenrun load estimates 10 ticks after the
3453289bdb4SPeter Zijlstra * CPUs have updated calc_load_tasks.
3463289bdb4SPeter Zijlstra *
3473289bdb4SPeter Zijlstra * Called from the global timer code.
3483289bdb4SPeter Zijlstra */
calc_global_load(void)34946132e3aSPaul Gortmaker void calc_global_load(void)
3503289bdb4SPeter Zijlstra {
351caeb5882SMatt Fleming unsigned long sample_window;
3523289bdb4SPeter Zijlstra long active, delta;
3533289bdb4SPeter Zijlstra
354caeb5882SMatt Fleming sample_window = READ_ONCE(calc_load_update);
355caeb5882SMatt Fleming if (time_before(jiffies, sample_window + 10))
3563289bdb4SPeter Zijlstra return;
3573289bdb4SPeter Zijlstra
3583289bdb4SPeter Zijlstra /*
35997fb7a0aSIngo Molnar * Fold the 'old' NO_HZ-delta to include all NO_HZ CPUs.
3603289bdb4SPeter Zijlstra */
361ebc0f83cSPeter Zijlstra (Intel) delta = calc_load_nohz_read();
3623289bdb4SPeter Zijlstra if (delta)
3633289bdb4SPeter Zijlstra atomic_long_add(delta, &calc_load_tasks);
3643289bdb4SPeter Zijlstra
3653289bdb4SPeter Zijlstra active = atomic_long_read(&calc_load_tasks);
3663289bdb4SPeter Zijlstra active = active > 0 ? active * FIXED_1 : 0;
3673289bdb4SPeter Zijlstra
3683289bdb4SPeter Zijlstra avenrun[0] = calc_load(avenrun[0], EXP_1, active);
3693289bdb4SPeter Zijlstra avenrun[1] = calc_load(avenrun[1], EXP_5, active);
3703289bdb4SPeter Zijlstra avenrun[2] = calc_load(avenrun[2], EXP_15, active);
3713289bdb4SPeter Zijlstra
372caeb5882SMatt Fleming WRITE_ONCE(calc_load_update, sample_window + LOAD_FREQ);
3733289bdb4SPeter Zijlstra
3743289bdb4SPeter Zijlstra /*
3753c85d6dbSFrederic Weisbecker * In case we went to NO_HZ for multiple LOAD_FREQ intervals
3763c85d6dbSFrederic Weisbecker * catch up in bulk.
3773289bdb4SPeter Zijlstra */
3783289bdb4SPeter Zijlstra calc_global_nohz();
3793289bdb4SPeter Zijlstra }
3803289bdb4SPeter Zijlstra
3813289bdb4SPeter Zijlstra /*
3823289bdb4SPeter Zijlstra * Called from scheduler_tick() to periodically update this CPU's
3833289bdb4SPeter Zijlstra * active count.
3843289bdb4SPeter Zijlstra */
calc_global_load_tick(struct rq * this_rq)3853289bdb4SPeter Zijlstra void calc_global_load_tick(struct rq *this_rq)
3863289bdb4SPeter Zijlstra {
3873289bdb4SPeter Zijlstra long delta;
3883289bdb4SPeter Zijlstra
3893289bdb4SPeter Zijlstra if (time_before(jiffies, this_rq->calc_load_update))
3903289bdb4SPeter Zijlstra return;
3913289bdb4SPeter Zijlstra
392d60585c5SThomas Gleixner delta = calc_load_fold_active(this_rq, 0);
3933289bdb4SPeter Zijlstra if (delta)
3943289bdb4SPeter Zijlstra atomic_long_add(delta, &calc_load_tasks);
3953289bdb4SPeter Zijlstra
3963289bdb4SPeter Zijlstra this_rq->calc_load_update += LOAD_FREQ;
3973289bdb4SPeter Zijlstra }
398