aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_rt.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched_rt.c')
-rw-r--r--kernel/sched_rt.c75
1 files changed, 62 insertions, 13 deletions
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 998ba54b4543..b446dc87494f 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -102,12 +102,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);
102 102
103static void sched_rt_rq_enqueue(struct rt_rq *rt_rq) 103static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
104{ 104{
105 struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
105 struct sched_rt_entity *rt_se = rt_rq->rt_se; 106 struct sched_rt_entity *rt_se = rt_rq->rt_se;
106 107
107 if (rt_se && !on_rt_rq(rt_se) && rt_rq->rt_nr_running) { 108 if (rt_rq->rt_nr_running) {
108 struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr; 109 if (rt_se && !on_rt_rq(rt_se))
109 110 enqueue_rt_entity(rt_se);
110 enqueue_rt_entity(rt_se);
111 if (rt_rq->highest_prio < curr->prio) 111 if (rt_rq->highest_prio < curr->prio)
112 resched_task(curr); 112 resched_task(curr);
113 } 113 }
@@ -199,6 +199,8 @@ static inline struct rt_rq *group_rt_rq(struct sched_rt_entity *rt_se)
199 199
200static inline void sched_rt_rq_enqueue(struct rt_rq *rt_rq) 200static inline void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
201{ 201{
202 if (rt_rq->rt_nr_running)
203 resched_task(rq_of_rt_rq(rt_rq)->curr);
202} 204}
203 205
204static inline void sched_rt_rq_dequeue(struct rt_rq *rt_rq) 206static inline void sched_rt_rq_dequeue(struct rt_rq *rt_rq)
@@ -229,6 +231,9 @@ static inline struct rt_bandwidth *sched_rt_bandwidth(struct rt_rq *rt_rq)
229#endif /* CONFIG_RT_GROUP_SCHED */ 231#endif /* CONFIG_RT_GROUP_SCHED */
230 232
231#ifdef CONFIG_SMP 233#ifdef CONFIG_SMP
234/*
235 * We ran out of runtime, see if we can borrow some from our neighbours.
236 */
232static int do_balance_runtime(struct rt_rq *rt_rq) 237static int do_balance_runtime(struct rt_rq *rt_rq)
233{ 238{
234 struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq); 239 struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
@@ -248,9 +253,18 @@ static int do_balance_runtime(struct rt_rq *rt_rq)
248 continue; 253 continue;
249 254
250 spin_lock(&iter->rt_runtime_lock); 255 spin_lock(&iter->rt_runtime_lock);
256 /*
257 * Either all rqs have inf runtime and there's nothing to steal
258 * or __disable_runtime() below sets a specific rq to inf to
259 * indicate its been disabled and disalow stealing.
260 */
251 if (iter->rt_runtime == RUNTIME_INF) 261 if (iter->rt_runtime == RUNTIME_INF)
252 goto next; 262 goto next;
253 263
264 /*
265 * From runqueues with spare time, take 1/n part of their
266 * spare time, but no more than our period.
267 */
254 diff = iter->rt_runtime - iter->rt_time; 268 diff = iter->rt_runtime - iter->rt_time;
255 if (diff > 0) { 269 if (diff > 0) {
256 diff = div_u64((u64)diff, weight); 270 diff = div_u64((u64)diff, weight);
@@ -272,6 +286,9 @@ next:
272 return more; 286 return more;
273} 287}
274 288
289/*
290 * Ensure this RQ takes back all the runtime it lend to its neighbours.
291 */
275static void __disable_runtime(struct rq *rq) 292static void __disable_runtime(struct rq *rq)
276{ 293{
277 struct root_domain *rd = rq->rd; 294 struct root_domain *rd = rq->rd;
@@ -287,17 +304,33 @@ static void __disable_runtime(struct rq *rq)
287 304
288 spin_lock(&rt_b->rt_runtime_lock); 305 spin_lock(&rt_b->rt_runtime_lock);
289 spin_lock(&rt_rq->rt_runtime_lock); 306 spin_lock(&rt_rq->rt_runtime_lock);
307 /*
308 * Either we're all inf and nobody needs to borrow, or we're
309 * already disabled and thus have nothing to do, or we have
310 * exactly the right amount of runtime to take out.
311 */
290 if (rt_rq->rt_runtime == RUNTIME_INF || 312 if (rt_rq->rt_runtime == RUNTIME_INF ||
291 rt_rq->rt_runtime == rt_b->rt_runtime) 313 rt_rq->rt_runtime == rt_b->rt_runtime)
292 goto balanced; 314 goto balanced;
293 spin_unlock(&rt_rq->rt_runtime_lock); 315 spin_unlock(&rt_rq->rt_runtime_lock);
294 316
317 /*
318 * Calculate the difference between what we started out with
319 * and what we current have, that's the amount of runtime
320 * we lend and now have to reclaim.
321 */
295 want = rt_b->rt_runtime - rt_rq->rt_runtime; 322 want = rt_b->rt_runtime - rt_rq->rt_runtime;
296 323
324 /*
325 * Greedy reclaim, take back as much as we can.
326 */
297 for_each_cpu_mask(i, rd->span) { 327 for_each_cpu_mask(i, rd->span) {
298 struct rt_rq *iter = sched_rt_period_rt_rq(rt_b, i); 328 struct rt_rq *iter = sched_rt_period_rt_rq(rt_b, i);
299 s64 diff; 329 s64 diff;
300 330
331 /*
332 * Can't reclaim from ourselves or disabled runqueues.
333 */
301 if (iter == rt_rq || iter->rt_runtime == RUNTIME_INF) 334 if (iter == rt_rq || iter->rt_runtime == RUNTIME_INF)
302 continue; 335 continue;
303 336
@@ -317,8 +350,16 @@ static void __disable_runtime(struct rq *rq)
317 } 350 }
318 351
319 spin_lock(&rt_rq->rt_runtime_lock); 352 spin_lock(&rt_rq->rt_runtime_lock);
353 /*
354 * We cannot be left wanting - that would mean some runtime
355 * leaked out of the system.
356 */
320 BUG_ON(want); 357 BUG_ON(want);
321balanced: 358balanced:
359 /*
360 * Disable all the borrow logic by pretending we have inf
361 * runtime - in which case borrowing doesn't make sense.
362 */
322 rt_rq->rt_runtime = RUNTIME_INF; 363 rt_rq->rt_runtime = RUNTIME_INF;
323 spin_unlock(&rt_rq->rt_runtime_lock); 364 spin_unlock(&rt_rq->rt_runtime_lock);
324 spin_unlock(&rt_b->rt_runtime_lock); 365 spin_unlock(&rt_b->rt_runtime_lock);
@@ -341,6 +382,9 @@ static void __enable_runtime(struct rq *rq)
341 if (unlikely(!scheduler_running)) 382 if (unlikely(!scheduler_running))
342 return; 383 return;
343 384
385 /*
386 * Reset each runqueue's bandwidth settings
387 */
344 for_each_leaf_rt_rq(rt_rq, rq) { 388 for_each_leaf_rt_rq(rt_rq, rq) {
345 struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq); 389 struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
346 390
@@ -348,6 +392,7 @@ static void __enable_runtime(struct rq *rq)
348 spin_lock(&rt_rq->rt_runtime_lock); 392 spin_lock(&rt_rq->rt_runtime_lock);
349 rt_rq->rt_runtime = rt_b->rt_runtime; 393 rt_rq->rt_runtime = rt_b->rt_runtime;
350 rt_rq->rt_time = 0; 394 rt_rq->rt_time = 0;
395 rt_rq->rt_throttled = 0;
351 spin_unlock(&rt_rq->rt_runtime_lock); 396 spin_unlock(&rt_rq->rt_runtime_lock);
352 spin_unlock(&rt_b->rt_runtime_lock); 397 spin_unlock(&rt_b->rt_runtime_lock);
353 } 398 }
@@ -386,7 +431,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
386 int i, idle = 1; 431 int i, idle = 1;
387 cpumask_t span; 432 cpumask_t span;
388 433
389 if (rt_b->rt_runtime == RUNTIME_INF) 434 if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF)
390 return 1; 435 return 1;
391 436
392 span = sched_rt_period_mask(); 437 span = sched_rt_period_mask();
@@ -438,9 +483,6 @@ static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
438{ 483{
439 u64 runtime = sched_rt_runtime(rt_rq); 484 u64 runtime = sched_rt_runtime(rt_rq);
440 485
441 if (runtime == RUNTIME_INF)
442 return 0;
443
444 if (rt_rq->rt_throttled) 486 if (rt_rq->rt_throttled)
445 return rt_rq_throttled(rt_rq); 487 return rt_rq_throttled(rt_rq);
446 488
@@ -484,16 +526,23 @@ static void update_curr_rt(struct rq *rq)
484 schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec)); 526 schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
485 527
486 curr->se.sum_exec_runtime += delta_exec; 528 curr->se.sum_exec_runtime += delta_exec;
529 account_group_exec_runtime(curr, delta_exec);
530
487 curr->se.exec_start = rq->clock; 531 curr->se.exec_start = rq->clock;
488 cpuacct_charge(curr, delta_exec); 532 cpuacct_charge(curr, delta_exec);
489 533
534 if (!rt_bandwidth_enabled())
535 return;
536
490 for_each_sched_rt_entity(rt_se) { 537 for_each_sched_rt_entity(rt_se) {
491 rt_rq = rt_rq_of_se(rt_se); 538 rt_rq = rt_rq_of_se(rt_se);
492 539
493 spin_lock(&rt_rq->rt_runtime_lock); 540 spin_lock(&rt_rq->rt_runtime_lock);
494 rt_rq->rt_time += delta_exec; 541 if (sched_rt_runtime(rt_rq) != RUNTIME_INF) {
495 if (sched_rt_runtime_exceeded(rt_rq)) 542 rt_rq->rt_time += delta_exec;
496 resched_task(curr); 543 if (sched_rt_runtime_exceeded(rt_rq))
544 resched_task(curr);
545 }
497 spin_unlock(&rt_rq->rt_runtime_lock); 546 spin_unlock(&rt_rq->rt_runtime_lock);
498 } 547 }
499} 548}
@@ -782,7 +831,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
782/* 831/*
783 * Preempt the current task with a newly woken task if needed: 832 * Preempt the current task with a newly woken task if needed:
784 */ 833 */
785static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p) 834static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int sync)
786{ 835{
787 if (p->prio < rq->curr->prio) { 836 if (p->prio < rq->curr->prio) {
788 resched_task(rq->curr); 837 resched_task(rq->curr);
@@ -1411,7 +1460,7 @@ static void watchdog(struct rq *rq, struct task_struct *p)
1411 p->rt.timeout++; 1460 p->rt.timeout++;
1412 next = DIV_ROUND_UP(min(soft, hard), USEC_PER_SEC/HZ); 1461 next = DIV_ROUND_UP(min(soft, hard), USEC_PER_SEC/HZ);
1413 if (p->rt.timeout > next) 1462 if (p->rt.timeout > next)
1414 p->it_sched_expires = p->se.sum_exec_runtime; 1463 p->cputime_expires.sched_exp = p->se.sum_exec_runtime;
1415 } 1464 }
1416} 1465}
1417 1466