Skip to content

Commit 48d5e25

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
sched: rt throttling vs no_hz
We need to teach no_hz about the rt throttling because its tick driven. Signed-off-by: Peter Zijlstra <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent 614ee1f commit 48d5e25

File tree

4 files changed

+45
-15
lines changed

4 files changed

+45
-15
lines changed

include/linux/sched.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ static inline int select_nohz_load_balancer(int cpu)
230230
}
231231
#endif
232232

233+
extern unsigned long rt_needs_cpu(int cpu);
234+
233235
/*
234236
* Only dump TASK_* tasks. (0 for all tasks)
235237
*/

kernel/sched.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ struct rq {
442442
struct cfs_rq cfs;
443443
struct rt_rq rt;
444444
u64 rt_period_expire;
445+
int rt_throttled;
445446

446447
#ifdef CONFIG_FAIR_GROUP_SCHED
447448
/* list of leaf cfs_rq on this cpu: */
@@ -594,6 +595,23 @@ static void update_rq_clock(struct rq *rq)
594595
#define task_rq(p) cpu_rq(task_cpu(p))
595596
#define cpu_curr(cpu) (cpu_rq(cpu)->curr)
596597

598+
unsigned long rt_needs_cpu(int cpu)
599+
{
600+
struct rq *rq = cpu_rq(cpu);
601+
u64 delta;
602+
603+
if (!rq->rt_throttled)
604+
return 0;
605+
606+
if (rq->clock > rq->rt_period_expire)
607+
return 1;
608+
609+
delta = rq->rt_period_expire - rq->clock;
610+
do_div(delta, NSEC_PER_SEC / HZ);
611+
612+
return (unsigned long)delta;
613+
}
614+
597615
/*
598616
* Tunables that become constants when CONFIG_SCHED_DEBUG is off:
599617
*/
@@ -7102,9 +7120,11 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq)
71027120
/* delimiter for bitsearch: */
71037121
__set_bit(MAX_RT_PRIO, array->bitmap);
71047122

7123+
#if defined CONFIG_SMP || defined CONFIG_FAIR_GROUP_SCHED
7124+
rt_rq->highest_prio = MAX_RT_PRIO;
7125+
#endif
71057126
#ifdef CONFIG_SMP
71067127
rt_rq->rt_nr_migratory = 0;
7107-
rt_rq->highest_prio = MAX_RT_PRIO;
71087128
rt_rq->overloaded = 0;
71097129
#endif
71107130

@@ -7191,6 +7211,7 @@ void __init sched_init(void)
71917211
&per_cpu(init_sched_rt_entity, i), i, 1);
71927212
#endif
71937213
rq->rt_period_expire = 0;
7214+
rq->rt_throttled = 0;
71947215

71957216
for (j = 0; j < CPU_LOAD_IDX_MAX; j++)
71967217
rq->cpu_load[j] = 0;

kernel/sched_rt.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,26 +175,18 @@ static int sched_rt_ratio_exceeded(struct rt_rq *rt_rq)
175175
ratio = (period * rt_ratio) >> SCHED_RT_FRAC_SHIFT;
176176

177177
if (rt_rq->rt_time > ratio) {
178+
struct rq *rq = rq_of_rt_rq(rt_rq);
179+
180+
rq->rt_throttled = 1;
178181
rt_rq->rt_throttled = 1;
182+
179183
sched_rt_ratio_dequeue(rt_rq);
180184
return 1;
181185
}
182186

183187
return 0;
184188
}
185189

186-
static void __update_sched_rt_period(struct rt_rq *rt_rq, u64 period)
187-
{
188-
unsigned long rt_ratio = sched_rt_ratio(rt_rq);
189-
u64 ratio = (period * rt_ratio) >> SCHED_RT_FRAC_SHIFT;
190-
191-
rt_rq->rt_time -= min(rt_rq->rt_time, ratio);
192-
if (rt_rq->rt_throttled) {
193-
rt_rq->rt_throttled = 0;
194-
sched_rt_ratio_enqueue(rt_rq);
195-
}
196-
}
197-
198190
static void update_sched_rt_period(struct rq *rq)
199191
{
200192
struct rt_rq *rt_rq;
@@ -204,8 +196,18 @@ static void update_sched_rt_period(struct rq *rq)
204196
period = (u64)sysctl_sched_rt_period * NSEC_PER_MSEC;
205197
rq->rt_period_expire += period;
206198

207-
for_each_leaf_rt_rq(rt_rq, rq)
208-
__update_sched_rt_period(rt_rq, period);
199+
for_each_leaf_rt_rq(rt_rq, rq) {
200+
unsigned long rt_ratio = sched_rt_ratio(rt_rq);
201+
u64 ratio = (period * rt_ratio) >> SCHED_RT_FRAC_SHIFT;
202+
203+
rt_rq->rt_time -= min(rt_rq->rt_time, ratio);
204+
if (rt_rq->rt_throttled) {
205+
rt_rq->rt_throttled = 0;
206+
sched_rt_ratio_enqueue(rt_rq);
207+
}
208+
}
209+
210+
rq->rt_throttled = 0;
209211
}
210212
}
211213

kernel/time/tick-sched.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ void tick_nohz_update_jiffies(void)
153153
void tick_nohz_stop_sched_tick(void)
154154
{
155155
unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags;
156+
unsigned long rt_jiffies;
156157
struct tick_sched *ts;
157158
ktime_t last_update, expires, now, delta;
158159
struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
@@ -216,6 +217,10 @@ void tick_nohz_stop_sched_tick(void)
216217
next_jiffies = get_next_timer_interrupt(last_jiffies);
217218
delta_jiffies = next_jiffies - last_jiffies;
218219

220+
rt_jiffies = rt_needs_cpu(cpu);
221+
if (rt_jiffies && rt_jiffies < delta_jiffies)
222+
delta_jiffies = rt_jiffies;
223+
219224
if (rcu_needs_cpu(cpu))
220225
delta_jiffies = 1;
221226
/*

0 commit comments

Comments
 (0)