diff options
Diffstat (limited to 'kernel/sched/cpufreq_schedutil.c')
-rw-r--r-- | kernel/sched/cpufreq_schedutil.c | 72 |
1 files changed, 32 insertions, 40 deletions
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 2efe629425be..962cf343f798 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/sched/cpufreq.h> | 13 | #include <linux/sched/cpufreq.h> |
14 | #include <trace/events/power.h> | 14 | #include <trace/events/power.h> |
15 | 15 | ||
16 | #define IOWAIT_BOOST_MIN (SCHED_CAPACITY_SCALE / 8) | ||
17 | |||
16 | struct sugov_tunables { | 18 | struct sugov_tunables { |
17 | struct gov_attr_set attr_set; | 19 | struct gov_attr_set attr_set; |
18 | unsigned int rate_limit_us; | 20 | unsigned int rate_limit_us; |
@@ -48,7 +50,6 @@ struct sugov_cpu { | |||
48 | 50 | ||
49 | bool iowait_boost_pending; | 51 | bool iowait_boost_pending; |
50 | unsigned int iowait_boost; | 52 | unsigned int iowait_boost; |
51 | unsigned int iowait_boost_max; | ||
52 | u64 last_update; | 53 | u64 last_update; |
53 | 54 | ||
54 | unsigned long bw_dl; | 55 | unsigned long bw_dl; |
@@ -291,8 +292,8 @@ static unsigned long sugov_get_util(struct sugov_cpu *sg_cpu) | |||
291 | * | 292 | * |
292 | * The IO wait boost of a task is disabled after a tick since the last update | 293 | * The IO wait boost of a task is disabled after a tick since the last update |
293 | * of a CPU. If a new IO wait boost is requested after more then a tick, then | 294 | * of a CPU. If a new IO wait boost is requested after more then a tick, then |
294 | * we enable the boost starting from the minimum frequency, which improves | 295 | * we enable the boost starting from IOWAIT_BOOST_MIN, which improves energy |
295 | * energy efficiency by ignoring sporadic wakeups from IO. | 296 | * efficiency by ignoring sporadic wakeups from IO. |
296 | */ | 297 | */ |
297 | static bool sugov_iowait_reset(struct sugov_cpu *sg_cpu, u64 time, | 298 | static bool sugov_iowait_reset(struct sugov_cpu *sg_cpu, u64 time, |
298 | bool set_iowait_boost) | 299 | bool set_iowait_boost) |
@@ -303,8 +304,7 @@ static bool sugov_iowait_reset(struct sugov_cpu *sg_cpu, u64 time, | |||
303 | if (delta_ns <= TICK_NSEC) | 304 | if (delta_ns <= TICK_NSEC) |
304 | return false; | 305 | return false; |
305 | 306 | ||
306 | sg_cpu->iowait_boost = set_iowait_boost | 307 | sg_cpu->iowait_boost = set_iowait_boost ? IOWAIT_BOOST_MIN : 0; |
307 | ? sg_cpu->sg_policy->policy->min : 0; | ||
308 | sg_cpu->iowait_boost_pending = set_iowait_boost; | 308 | sg_cpu->iowait_boost_pending = set_iowait_boost; |
309 | 309 | ||
310 | return true; | 310 | return true; |
@@ -318,8 +318,9 @@ static bool sugov_iowait_reset(struct sugov_cpu *sg_cpu, u64 time, | |||
318 | * | 318 | * |
319 | * Each time a task wakes up after an IO operation, the CPU utilization can be | 319 | * Each time a task wakes up after an IO operation, the CPU utilization can be |
320 | * boosted to a certain utilization which doubles at each "frequent and | 320 | * boosted to a certain utilization which doubles at each "frequent and |
321 | * successive" wakeup from IO, ranging from the utilization of the minimum | 321 | * successive" wakeup from IO, ranging from IOWAIT_BOOST_MIN to the utilization |
322 | * OPP to the utilization of the maximum OPP. | 322 | * of the maximum OPP. |
323 | * | ||
323 | * To keep doubling, an IO boost has to be requested at least once per tick, | 324 | * To keep doubling, an IO boost has to be requested at least once per tick, |
324 | * otherwise we restart from the utilization of the minimum OPP. | 325 | * otherwise we restart from the utilization of the minimum OPP. |
325 | */ | 326 | */ |
@@ -344,14 +345,13 @@ static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, u64 time, | |||
344 | 345 | ||
345 | /* Double the boost at each request */ | 346 | /* Double the boost at each request */ |
346 | if (sg_cpu->iowait_boost) { | 347 | if (sg_cpu->iowait_boost) { |
347 | sg_cpu->iowait_boost <<= 1; | 348 | sg_cpu->iowait_boost = |
348 | if (sg_cpu->iowait_boost > sg_cpu->iowait_boost_max) | 349 | min_t(unsigned int, sg_cpu->iowait_boost << 1, SCHED_CAPACITY_SCALE); |
349 | sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; | ||
350 | return; | 350 | return; |
351 | } | 351 | } |
352 | 352 | ||
353 | /* First wakeup after IO: start with minimum boost */ | 353 | /* First wakeup after IO: start with minimum boost */ |
354 | sg_cpu->iowait_boost = sg_cpu->sg_policy->policy->min; | 354 | sg_cpu->iowait_boost = IOWAIT_BOOST_MIN; |
355 | } | 355 | } |
356 | 356 | ||
357 | /** | 357 | /** |
@@ -373,47 +373,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 | 373 | * This mechanism is designed to boost high frequently IO waiting tasks, while |
374 | * being more conservative on tasks which does sporadic IO operations. | 374 | * being more conservative on tasks which does sporadic IO operations. |
375 | */ | 375 | */ |
376 | static void sugov_iowait_apply(struct sugov_cpu *sg_cpu, u64 time, | 376 | static unsigned long sugov_iowait_apply(struct sugov_cpu *sg_cpu, u64 time, |
377 | unsigned long *util, unsigned long *max) | 377 | unsigned long util, unsigned long max) |
378 | { | 378 | { |
379 | unsigned int boost_util, boost_max; | 379 | unsigned long boost; |
380 | 380 | ||
381 | /* No boost currently required */ | 381 | /* No boost currently required */ |
382 | if (!sg_cpu->iowait_boost) | 382 | if (!sg_cpu->iowait_boost) |
383 | return; | 383 | return util; |
384 | 384 | ||
385 | /* Reset boost if the CPU appears to have been idle enough */ | 385 | /* Reset boost if the CPU appears to have been idle enough */ |
386 | if (sugov_iowait_reset(sg_cpu, time, false)) | 386 | if (sugov_iowait_reset(sg_cpu, time, false)) |
387 | return; | 387 | return util; |
388 | 388 | ||
389 | /* | 389 | 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 | /* | 390 | /* |
397 | * Otherwise: reduce the boost value and disable it when we | 391 | * No boost pending; reduce the boost value. |
398 | * reach the minimum. | ||
399 | */ | 392 | */ |
400 | sg_cpu->iowait_boost >>= 1; | 393 | sg_cpu->iowait_boost >>= 1; |
401 | if (sg_cpu->iowait_boost < sg_cpu->sg_policy->policy->min) { | 394 | if (sg_cpu->iowait_boost < IOWAIT_BOOST_MIN) { |
402 | sg_cpu->iowait_boost = 0; | 395 | sg_cpu->iowait_boost = 0; |
403 | return; | 396 | return util; |
404 | } | 397 | } |
405 | } | 398 | } |
406 | 399 | ||
400 | sg_cpu->iowait_boost_pending = false; | ||
401 | |||
407 | /* | 402 | /* |
408 | * Apply the current boost value: a CPU is boosted only if its current | 403 | * @util is already in capacity scale; convert iowait_boost |
409 | * utilization is smaller then the current IO boost level. | 404 | * into the same scale so we can compare. |
410 | */ | 405 | */ |
411 | boost_util = sg_cpu->iowait_boost; | 406 | boost = (sg_cpu->iowait_boost * max) >> SCHED_CAPACITY_SHIFT; |
412 | boost_max = sg_cpu->iowait_boost_max; | 407 | return max(boost, util); |
413 | if (*util * boost_max < *max * boost_util) { | ||
414 | *util = boost_util; | ||
415 | *max = boost_max; | ||
416 | } | ||
417 | } | 408 | } |
418 | 409 | ||
419 | #ifdef CONFIG_NO_HZ_COMMON | 410 | #ifdef CONFIG_NO_HZ_COMMON |
@@ -460,7 +451,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, | |||
460 | 451 | ||
461 | util = sugov_get_util(sg_cpu); | 452 | util = sugov_get_util(sg_cpu); |
462 | max = sg_cpu->max; | 453 | max = sg_cpu->max; |
463 | sugov_iowait_apply(sg_cpu, time, &util, &max); | 454 | util = sugov_iowait_apply(sg_cpu, time, util, max); |
464 | next_f = get_next_freq(sg_policy, util, max); | 455 | next_f = get_next_freq(sg_policy, util, max); |
465 | /* | 456 | /* |
466 | * Do not reduce the frequency if the CPU has not been idle | 457 | * Do not reduce the frequency if the CPU has not been idle |
@@ -500,7 +491,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time) | |||
500 | 491 | ||
501 | j_util = sugov_get_util(j_sg_cpu); | 492 | j_util = sugov_get_util(j_sg_cpu); |
502 | j_max = j_sg_cpu->max; | 493 | j_max = j_sg_cpu->max; |
503 | sugov_iowait_apply(j_sg_cpu, time, &j_util, &j_max); | 494 | j_util = sugov_iowait_apply(j_sg_cpu, time, j_util, j_max); |
504 | 495 | ||
505 | if (j_util * max > j_max * util) { | 496 | if (j_util * max > j_max * util) { |
506 | util = j_util; | 497 | util = j_util; |
@@ -609,13 +600,14 @@ rate_limit_us_store(struct gov_attr_set *attr_set, const char *buf, size_t count | |||
609 | 600 | ||
610 | static struct governor_attr rate_limit_us = __ATTR_RW(rate_limit_us); | 601 | static struct governor_attr rate_limit_us = __ATTR_RW(rate_limit_us); |
611 | 602 | ||
612 | static struct attribute *sugov_attributes[] = { | 603 | static struct attribute *sugov_attrs[] = { |
613 | &rate_limit_us.attr, | 604 | &rate_limit_us.attr, |
614 | NULL | 605 | NULL |
615 | }; | 606 | }; |
607 | ATTRIBUTE_GROUPS(sugov); | ||
616 | 608 | ||
617 | static struct kobj_type sugov_tunables_ktype = { | 609 | static struct kobj_type sugov_tunables_ktype = { |
618 | .default_attrs = sugov_attributes, | 610 | .default_groups = sugov_groups, |
619 | .sysfs_ops = &governor_sysfs_ops, | 611 | .sysfs_ops = &governor_sysfs_ops, |
620 | }; | 612 | }; |
621 | 613 | ||
@@ -782,6 +774,7 @@ out: | |||
782 | return 0; | 774 | return 0; |
783 | 775 | ||
784 | fail: | 776 | fail: |
777 | kobject_put(&tunables->attr_set.kobj); | ||
785 | policy->governor_data = NULL; | 778 | policy->governor_data = NULL; |
786 | sugov_tunables_free(tunables); | 779 | sugov_tunables_free(tunables); |
787 | 780 | ||
@@ -837,7 +830,6 @@ static int sugov_start(struct cpufreq_policy *policy) | |||
837 | memset(sg_cpu, 0, sizeof(*sg_cpu)); | 830 | memset(sg_cpu, 0, sizeof(*sg_cpu)); |
838 | sg_cpu->cpu = cpu; | 831 | sg_cpu->cpu = cpu; |
839 | sg_cpu->sg_policy = sg_policy; | 832 | sg_cpu->sg_policy = sg_policy; |
840 | sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq; | ||
841 | } | 833 | } |
842 | 834 | ||
843 | for_each_cpu(cpu, policy->cpus) { | 835 | for_each_cpu(cpu, policy->cpus) { |