diff options
| -rw-r--r-- | kernel/sched/cpufreq_schedutil.c | 59 |
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 | */ |
| 376 | static void sugov_iowait_apply(struct sugov_cpu *sg_cpu, u64 time, | 374 | static 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) { |
