Skip to content

Commit 5e83eaf

Browse files
deggemanIngo Molnar
authored andcommitted
sched/fair: Remove the rq->cpu_load[] update code
With LB_BIAS disabled, there is no need to update the rq->cpu_load[idx] any more. Signed-off-by: Dietmar Eggemann <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Rik van Riel <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Morten Rasmussen <[email protected]> Cc: Patrick Bellasi <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Quentin Perret <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Valentin Schneider <[email protected]> Cc: Vincent Guittot <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent f2bedc4 commit 5e83eaf

File tree

5 files changed

+0
-272
lines changed

5 files changed

+0
-272
lines changed

include/linux/sched/nohz.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@
66
* This is the interface between the scheduler and nohz/dynticks:
77
*/
88

9-
#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON)
10-
extern void cpu_load_update_nohz_start(void);
11-
extern void cpu_load_update_nohz_stop(void);
12-
#else
13-
static inline void cpu_load_update_nohz_start(void) { }
14-
static inline void cpu_load_update_nohz_stop(void) { }
15-
#endif
16-
179
#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON)
1810
extern void nohz_balance_enter_idle(int cpu);
1911
extern int get_nohz_timer_target(void);

kernel/sched/core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3033,7 +3033,6 @@ void scheduler_tick(void)
30333033

30343034
update_rq_clock(rq);
30353035
curr->sched_class->task_tick(rq, curr, 0);
3036-
cpu_load_update_active(rq);
30373036
calc_global_load_tick(rq);
30383037
psi_task_tick(rq);
30393038

kernel/sched/fair.c

Lines changed: 0 additions & 255 deletions
Original file line numberDiff line numberDiff line change
@@ -5322,71 +5322,6 @@ DEFINE_PER_CPU(cpumask_var_t, load_balance_mask);
53225322
DEFINE_PER_CPU(cpumask_var_t, select_idle_mask);
53235323

53245324
#ifdef CONFIG_NO_HZ_COMMON
5325-
/*
5326-
* per rq 'load' arrray crap; XXX kill this.
5327-
*/
5328-
5329-
/*
5330-
* The exact cpuload calculated at every tick would be:
5331-
*
5332-
* load' = (1 - 1/2^i) * load + (1/2^i) * cur_load
5333-
*
5334-
* If a CPU misses updates for n ticks (as it was idle) and update gets
5335-
* called on the n+1-th tick when CPU may be busy, then we have:
5336-
*
5337-
* load_n = (1 - 1/2^i)^n * load_0
5338-
* load_n+1 = (1 - 1/2^i) * load_n + (1/2^i) * cur_load
5339-
*
5340-
* decay_load_missed() below does efficient calculation of
5341-
*
5342-
* load' = (1 - 1/2^i)^n * load
5343-
*
5344-
* Because x^(n+m) := x^n * x^m we can decompose any x^n in power-of-2 factors.
5345-
* This allows us to precompute the above in said factors, thereby allowing the
5346-
* reduction of an arbitrary n in O(log_2 n) steps. (See also
5347-
* fixed_power_int())
5348-
*
5349-
* The calculation is approximated on a 128 point scale.
5350-
*/
5351-
#define DEGRADE_SHIFT 7
5352-
5353-
static const u8 degrade_zero_ticks[CPU_LOAD_IDX_MAX] = {0, 8, 32, 64, 128};
5354-
static const u8 degrade_factor[CPU_LOAD_IDX_MAX][DEGRADE_SHIFT + 1] = {
5355-
{ 0, 0, 0, 0, 0, 0, 0, 0 },
5356-
{ 64, 32, 8, 0, 0, 0, 0, 0 },
5357-
{ 96, 72, 40, 12, 1, 0, 0, 0 },
5358-
{ 112, 98, 75, 43, 15, 1, 0, 0 },
5359-
{ 120, 112, 98, 76, 45, 16, 2, 0 }
5360-
};
5361-
5362-
/*
5363-
* Update cpu_load for any missed ticks, due to tickless idle. The backlog
5364-
* would be when CPU is idle and so we just decay the old load without
5365-
* adding any new load.
5366-
*/
5367-
static unsigned long
5368-
decay_load_missed(unsigned long load, unsigned long missed_updates, int idx)
5369-
{
5370-
int j = 0;
5371-
5372-
if (!missed_updates)
5373-
return load;
5374-
5375-
if (missed_updates >= degrade_zero_ticks[idx])
5376-
return 0;
5377-
5378-
if (idx == 1)
5379-
return load >> missed_updates;
5380-
5381-
while (missed_updates) {
5382-
if (missed_updates % 2)
5383-
load = (load * degrade_factor[idx][j]) >> DEGRADE_SHIFT;
5384-
5385-
missed_updates >>= 1;
5386-
j++;
5387-
}
5388-
return load;
5389-
}
53905325

53915326
static struct {
53925327
cpumask_var_t idle_cpus_mask;
@@ -5398,201 +5333,12 @@ static struct {
53985333

53995334
#endif /* CONFIG_NO_HZ_COMMON */
54005335

5401-
/**
5402-
* __cpu_load_update - update the rq->cpu_load[] statistics
5403-
* @this_rq: The rq to update statistics for
5404-
* @this_load: The current load
5405-
* @pending_updates: The number of missed updates
5406-
*
5407-
* Update rq->cpu_load[] statistics. This function is usually called every
5408-
* scheduler tick (TICK_NSEC).
5409-
*
5410-
* This function computes a decaying average:
5411-
*
5412-
* load[i]' = (1 - 1/2^i) * load[i] + (1/2^i) * load
5413-
*
5414-
* Because of NOHZ it might not get called on every tick which gives need for
5415-
* the @pending_updates argument.
5416-
*
5417-
* load[i]_n = (1 - 1/2^i) * load[i]_n-1 + (1/2^i) * load_n-1
5418-
* = A * load[i]_n-1 + B ; A := (1 - 1/2^i), B := (1/2^i) * load
5419-
* = A * (A * load[i]_n-2 + B) + B
5420-
* = A * (A * (A * load[i]_n-3 + B) + B) + B
5421-
* = A^3 * load[i]_n-3 + (A^2 + A + 1) * B
5422-
* = A^n * load[i]_0 + (A^(n-1) + A^(n-2) + ... + 1) * B
5423-
* = A^n * load[i]_0 + ((1 - A^n) / (1 - A)) * B
5424-
* = (1 - 1/2^i)^n * (load[i]_0 - load) + load
5425-
*
5426-
* In the above we've assumed load_n := load, which is true for NOHZ_FULL as
5427-
* any change in load would have resulted in the tick being turned back on.
5428-
*
5429-
* For regular NOHZ, this reduces to:
5430-
*
5431-
* load[i]_n = (1 - 1/2^i)^n * load[i]_0
5432-
*
5433-
* see decay_load_misses(). For NOHZ_FULL we get to subtract and add the extra
5434-
* term.
5435-
*/
5436-
static void cpu_load_update(struct rq *this_rq, unsigned long this_load,
5437-
unsigned long pending_updates)
5438-
{
5439-
unsigned long __maybe_unused tickless_load = this_rq->cpu_load[0];
5440-
int i, scale;
5441-
5442-
this_rq->nr_load_updates++;
5443-
5444-
/* Update our load: */
5445-
this_rq->cpu_load[0] = this_load; /* Fasttrack for idx 0 */
5446-
for (i = 1, scale = 2; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
5447-
unsigned long old_load, new_load;
5448-
5449-
/* scale is effectively 1 << i now, and >> i divides by scale */
5450-
5451-
old_load = this_rq->cpu_load[i];
5452-
#ifdef CONFIG_NO_HZ_COMMON
5453-
old_load = decay_load_missed(old_load, pending_updates - 1, i);
5454-
if (tickless_load) {
5455-
old_load -= decay_load_missed(tickless_load, pending_updates - 1, i);
5456-
/*
5457-
* old_load can never be a negative value because a
5458-
* decayed tickless_load cannot be greater than the
5459-
* original tickless_load.
5460-
*/
5461-
old_load += tickless_load;
5462-
}
5463-
#endif
5464-
new_load = this_load;
5465-
/*
5466-
* Round up the averaging division if load is increasing. This
5467-
* prevents us from getting stuck on 9 if the load is 10, for
5468-
* example.
5469-
*/
5470-
if (new_load > old_load)
5471-
new_load += scale - 1;
5472-
5473-
this_rq->cpu_load[i] = (old_load * (scale - 1) + new_load) >> i;
5474-
}
5475-
}
5476-
54775336
/* Used instead of source_load when we know the type == 0 */
54785337
static unsigned long weighted_cpuload(struct rq *rq)
54795338
{
54805339
return cfs_rq_runnable_load_avg(&rq->cfs);
54815340
}
54825341

5483-
#ifdef CONFIG_NO_HZ_COMMON
5484-
/*
5485-
* There is no sane way to deal with nohz on smp when using jiffies because the
5486-
* CPU doing the jiffies update might drift wrt the CPU doing the jiffy reading
5487-
* causing off-by-one errors in observed deltas; {0,2} instead of {1,1}.
5488-
*
5489-
* Therefore we need to avoid the delta approach from the regular tick when
5490-
* possible since that would seriously skew the load calculation. This is why we
5491-
* use cpu_load_update_periodic() for CPUs out of nohz. However we'll rely on
5492-
* jiffies deltas for updates happening while in nohz mode (idle ticks, idle
5493-
* loop exit, nohz_idle_balance, nohz full exit...)
5494-
*
5495-
* This means we might still be one tick off for nohz periods.
5496-
*/
5497-
5498-
static void cpu_load_update_nohz(struct rq *this_rq,
5499-
unsigned long curr_jiffies,
5500-
unsigned long load)
5501-
{
5502-
unsigned long pending_updates;
5503-
5504-
pending_updates = curr_jiffies - this_rq->last_load_update_tick;
5505-
if (pending_updates) {
5506-
this_rq->last_load_update_tick = curr_jiffies;
5507-
/*
5508-
* In the regular NOHZ case, we were idle, this means load 0.
5509-
* In the NOHZ_FULL case, we were non-idle, we should consider
5510-
* its weighted load.
5511-
*/
5512-
cpu_load_update(this_rq, load, pending_updates);
5513-
}
5514-
}
5515-
5516-
/*
5517-
* Called from nohz_idle_balance() to update the load ratings before doing the
5518-
* idle balance.
5519-
*/
5520-
static void cpu_load_update_idle(struct rq *this_rq)
5521-
{
5522-
/*
5523-
* bail if there's load or we're actually up-to-date.
5524-
*/
5525-
if (weighted_cpuload(this_rq))
5526-
return;
5527-
5528-
cpu_load_update_nohz(this_rq, READ_ONCE(jiffies), 0);
5529-
}
5530-
5531-
/*
5532-
* Record CPU load on nohz entry so we know the tickless load to account
5533-
* on nohz exit. cpu_load[0] happens then to be updated more frequently
5534-
* than other cpu_load[idx] but it should be fine as cpu_load readers
5535-
* shouldn't rely into synchronized cpu_load[*] updates.
5536-
*/
5537-
void cpu_load_update_nohz_start(void)
5538-
{
5539-
struct rq *this_rq = this_rq();
5540-
5541-
/*
5542-
* This is all lockless but should be fine. If weighted_cpuload changes
5543-
* concurrently we'll exit nohz. And cpu_load write can race with
5544-
* cpu_load_update_idle() but both updater would be writing the same.
5545-
*/
5546-
this_rq->cpu_load[0] = weighted_cpuload(this_rq);
5547-
}
5548-
5549-
/*
5550-
* Account the tickless load in the end of a nohz frame.
5551-
*/
5552-
void cpu_load_update_nohz_stop(void)
5553-
{
5554-
unsigned long curr_jiffies = READ_ONCE(jiffies);
5555-
struct rq *this_rq = this_rq();
5556-
unsigned long load;
5557-
struct rq_flags rf;
5558-
5559-
if (curr_jiffies == this_rq->last_load_update_tick)
5560-
return;
5561-
5562-
load = weighted_cpuload(this_rq);
5563-
rq_lock(this_rq, &rf);
5564-
update_rq_clock(this_rq);
5565-
cpu_load_update_nohz(this_rq, curr_jiffies, load);
5566-
rq_unlock(this_rq, &rf);
5567-
}
5568-
#else /* !CONFIG_NO_HZ_COMMON */
5569-
static inline void cpu_load_update_nohz(struct rq *this_rq,
5570-
unsigned long curr_jiffies,
5571-
unsigned long load) { }
5572-
#endif /* CONFIG_NO_HZ_COMMON */
5573-
5574-
static void cpu_load_update_periodic(struct rq *this_rq, unsigned long load)
5575-
{
5576-
#ifdef CONFIG_NO_HZ_COMMON
5577-
/* See the mess around cpu_load_update_nohz(). */
5578-
this_rq->last_load_update_tick = READ_ONCE(jiffies);
5579-
#endif
5580-
cpu_load_update(this_rq, load, 1);
5581-
}
5582-
5583-
/*
5584-
* Called from scheduler_tick()
5585-
*/
5586-
void cpu_load_update_active(struct rq *this_rq)
5587-
{
5588-
unsigned long load = weighted_cpuload(this_rq);
5589-
5590-
if (tick_nohz_tick_stopped())
5591-
cpu_load_update_nohz(this_rq, READ_ONCE(jiffies), load);
5592-
else
5593-
cpu_load_update_periodic(this_rq, load);
5594-
}
5595-
55965342
/*
55975343
* Return a low guess at the load of a migration-source CPU weighted
55985344
* according to the scheduling class and "nice" value.
@@ -9876,7 +9622,6 @@ static bool _nohz_idle_balance(struct rq *this_rq, unsigned int flags,
98769622

98779623
rq_lock_irqsave(rq, &rf);
98789624
update_rq_clock(rq);
9879-
cpu_load_update_idle(rq);
98809625
rq_unlock_irqrestore(rq, &rf);
98819626

98829627
if (flags & NOHZ_BALANCE_KICK)

kernel/sched/sched.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,6 @@ extern atomic_long_t calc_load_tasks;
9696
extern void calc_global_load_tick(struct rq *this_rq);
9797
extern long calc_load_fold_active(struct rq *this_rq, long adjust);
9898

99-
#ifdef CONFIG_SMP
100-
extern void cpu_load_update_active(struct rq *this_rq);
101-
#else
102-
static inline void cpu_load_update_active(struct rq *this_rq) { }
103-
#endif
104-
10599
/*
106100
* Helpers for converting nanosecond timing to jiffy resolution
107101
*/

kernel/time/tick-sched.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,6 @@ static void tick_nohz_stop_tick(struct tick_sched *ts, int cpu)
782782
*/
783783
if (!ts->tick_stopped) {
784784
calc_load_nohz_start();
785-
cpu_load_update_nohz_start();
786785
quiet_vmstat();
787786

788787
ts->last_tick = hrtimer_get_expires(&ts->sched_timer);
@@ -829,7 +828,6 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now)
829828
{
830829
/* Update jiffies first */
831830
tick_do_update_jiffies64(now);
832-
cpu_load_update_nohz_stop();
833831

834832
/*
835833
* Clear the timer idle flag, so we avoid IPIs on remote queueing and

0 commit comments

Comments
 (0)