aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/sched/cpufreq_schedutil.c59
1 files changed, 25 insertions, 34 deletions
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 033ec7c45f13..1ccf77f6d346 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -48,10 +48,10 @@ struct sugov_cpu {
48 48
49 bool iowait_boost_pending; 49 bool iowait_boost_pending;
50 unsigned int iowait_boost; 50 unsigned int iowait_boost;
51 unsigned int iowait_boost_max;
52 u64 last_update; 51 u64 last_update;
53 52
54 unsigned long bw_dl; 53 unsigned long bw_dl;
54 unsigned long min;
55 unsigned long max; 55 unsigned long max;
56 56
57 /* The field below is for single-CPU policies only: */ 57 /* The field below is for single-CPU policies only: */
@@ -303,8 +303,7 @@ static bool sugov_iowait_reset(struct sugov_cpu *sg_cpu, u64 time,
303 if (delta_ns <= TICK_NSEC) 303 if (delta_ns <= TICK_NSEC)
304 return false; 304 return false;
305 305
306 sg_cpu->iowait_boost = set_iowait_boost 306 sg_cpu->iowait_boost = set_iowait_boost ? sg_cpu->min : 0;
307 ? sg_cpu->sg_policy->policy->min : 0;
308 sg_cpu->iowait_boost_pending = set_iowait_boost; 307 sg_cpu->iowait_boost_pending = set_iowait_boost;
309 308
310 return true; 309 return true;
@@ -344,14 +343,13 @@ static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
344 343
345 /* Double the boost at each request */ 344 /* Double the boost at each request */
346 if (sg_cpu->iowait_boost) { 345 if (sg_cpu->iowait_boost) {
347 sg_cpu->iowait_boost <<= 1; 346 sg_cpu->iowait_boost =
348 if (sg_cpu->iowait_boost > sg_cpu->iowait_boost_max) 347 min_t(unsigned int, sg_cpu->iowait_boost << 1, SCHED_CAPACITY_SCALE);
349 sg_cpu->iowait_boost = sg_cpu->iowait_boost_max;
350 return; 348 return;
351 } 349 }
352 350
353 /* First wakeup after IO: start with minimum boost */ 351 /* First wakeup after IO: start with minimum boost */
354 sg_cpu->iowait_boost = sg_cpu->sg_policy->policy->min; 352 sg_cpu->iowait_boost = sg_cpu->min;
355} 353}
356 354
357/** 355/**
@@ -373,47 +371,38 @@ static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
373 * This mechanism is designed to boost high frequently IO waiting tasks, while 371 * This mechanism is designed to boost high frequently IO waiting tasks, while
374 * being more conservative on tasks which does sporadic IO operations. 372 * being more conservative on tasks which does sporadic IO operations.
375 */ 373 */
376static void sugov_iowait_apply(struct sugov_cpu *sg_cpu, u64 time, 374static unsigned long sugov_iowait_apply(struct sugov_cpu *sg_cpu, u64 time,
377 unsigned long *util, unsigned long *max) 375 unsigned long util, unsigned long max)
378{ 376{
379 unsigned int boost_util, boost_max; 377 unsigned long boost;
380 378
381 /* No boost currently required */ 379 /* No boost currently required */
382 if (!sg_cpu->iowait_boost) 380 if (!sg_cpu->iowait_boost)
383 return; 381 return util;
384 382
385 /* Reset boost if the CPU appears to have been idle enough */ 383 /* Reset boost if the CPU appears to have been idle enough */
386 if (sugov_iowait_reset(sg_cpu, time, false)) 384 if (sugov_iowait_reset(sg_cpu, time, false))
387 return; 385 return util;
388 386
389 /* 387 if (!sg_cpu->iowait_boost_pending) {
390 * An IO waiting task has just woken up:
391 * allow to further double the boost value
392 */
393 if (sg_cpu->iowait_boost_pending) {
394 sg_cpu->iowait_boost_pending = false;
395 } else {
396 /* 388 /*
397 * Otherwise: reduce the boost value and disable it when we 389 * No boost pending; reduce the boost value.
398 * reach the minimum.
399 */ 390 */
400 sg_cpu->iowait_boost >>= 1; 391 sg_cpu->iowait_boost >>= 1;
401 if (sg_cpu->iowait_boost < sg_cpu->sg_policy->policy->min) { 392 if (sg_cpu->iowait_boost < sg_cpu->min) {
402 sg_cpu->iowait_boost = 0; 393 sg_cpu->iowait_boost = 0;
403 return; 394 return util;
404 } 395 }
405 } 396 }
406 397
398 sg_cpu->iowait_boost_pending = false;
399
407 /* 400 /*
408 * Apply the current boost value: a CPU is boosted only if its current 401 * @util is already in capacity scale; convert iowait_boost
409 * utilization is smaller then the current IO boost level. 402 * into the same scale so we can compare.
410 */ 403 */
411 boost_util = sg_cpu->iowait_boost; 404 boost = (sg_cpu->iowait_boost * max) >> SCHED_CAPACITY_SHIFT;
412 boost_max = sg_cpu->iowait_boost_max; 405 return max(boost, util);
413 if (*util * boost_max < *max * boost_util) {
414 *util = boost_util;
415 *max = boost_max;
416 }
417} 406}
418 407
419#ifdef CONFIG_NO_HZ_COMMON 408#ifdef CONFIG_NO_HZ_COMMON
@@ -460,7 +449,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
460 449
461 util = sugov_get_util(sg_cpu); 450 util = sugov_get_util(sg_cpu);
462 max = sg_cpu->max; 451 max = sg_cpu->max;
463 sugov_iowait_apply(sg_cpu, time, &util, &max); 452 util = sugov_iowait_apply(sg_cpu, time, util, max);
464 next_f = get_next_freq(sg_policy, util, max); 453 next_f = get_next_freq(sg_policy, util, max);
465 /* 454 /*
466 * Do not reduce the frequency if the CPU has not been idle 455 * Do not reduce the frequency if the CPU has not been idle
@@ -500,7 +489,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time)
500 489
501 j_util = sugov_get_util(j_sg_cpu); 490 j_util = sugov_get_util(j_sg_cpu);
502 j_max = j_sg_cpu->max; 491 j_max = j_sg_cpu->max;
503 sugov_iowait_apply(j_sg_cpu, time, &j_util, &j_max); 492 j_util = sugov_iowait_apply(j_sg_cpu, time, j_util, j_max);
504 493
505 if (j_util * max > j_max * util) { 494 if (j_util * max > j_max * util) {
506 util = j_util; 495 util = j_util;
@@ -837,7 +826,9 @@ static int sugov_start(struct cpufreq_policy *policy)
837 memset(sg_cpu, 0, sizeof(*sg_cpu)); 826 memset(sg_cpu, 0, sizeof(*sg_cpu));
838 sg_cpu->cpu = cpu; 827 sg_cpu->cpu = cpu;
839 sg_cpu->sg_policy = sg_policy; 828 sg_cpu->sg_policy = sg_policy;
840 sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq; 829 sg_cpu->min =
830 (SCHED_CAPACITY_SCALE * policy->cpuinfo.min_freq) /
831 policy->cpuinfo.max_freq;
841 } 832 }
842 833
843 for_each_cpu(cpu, policy->cpus) { 834 for_each_cpu(cpu, policy->cpus) {