diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2008-04-18 16:31:12 -0400 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2008-04-28 16:27:08 -0400 |
commit | e8628dd06d66f2e3965ec9742029b401d63434f1 (patch) | |
tree | 341d5a2e36c877bd52c5567aa5791557a6920557 | |
parent | e56a727b023d40d1adf660168883f30f2e6abe0a (diff) |
[CPUFREQ] expose cpufreq coordination requirements regardless of coordination mechanism
Currently, affected_cpus shows which CPUs need to have their frequency
coordinated in software. When hardware coordination is in use, the contents
of this file appear the same as when no coordination is required. This can
lead to some confusion among user-space programs, for example, that do not
know that extra coordination is required to force a CPU core to a particular
speed to control power consumption.
To fix this, create a "related_cpus" attribute that always displays the
coordination map regardless of whatever coordination strategy the cpufreq
driver uses (sw or hw). If the cpufreq driver does not provide a value, fall
back to policy->cpus.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dave Jones <davej@redhat.com>
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 1 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 29 | ||||
-rw-r--r-- | include/linux/cpufreq.h | 3 |
3 files changed, 27 insertions, 6 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 8db8f73503b3..b0c8208df9fa 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -601,6 +601,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
601 | policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { | 601 | policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { |
602 | policy->cpus = perf->shared_cpu_map; | 602 | policy->cpus = perf->shared_cpu_map; |
603 | } | 603 | } |
604 | policy->related_cpus = perf->shared_cpu_map; | ||
604 | 605 | ||
605 | #ifdef CONFIG_SMP | 606 | #ifdef CONFIG_SMP |
606 | dmi_check_system(sw_any_bug_dmi_table); | 607 | dmi_check_system(sw_any_bug_dmi_table); |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index d3575f5ec6d2..7fce038fa57e 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -583,15 +583,13 @@ out: | |||
583 | i += sprintf(&buf[i], "\n"); | 583 | i += sprintf(&buf[i], "\n"); |
584 | return i; | 584 | return i; |
585 | } | 585 | } |
586 | /** | 586 | |
587 | * show_affected_cpus - show the CPUs affected by each transition | 587 | static ssize_t show_cpus(cpumask_t mask, char *buf) |
588 | */ | ||
589 | static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) | ||
590 | { | 588 | { |
591 | ssize_t i = 0; | 589 | ssize_t i = 0; |
592 | unsigned int cpu; | 590 | unsigned int cpu; |
593 | 591 | ||
594 | for_each_cpu_mask(cpu, policy->cpus) { | 592 | for_each_cpu_mask(cpu, mask) { |
595 | if (i) | 593 | if (i) |
596 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " "); | 594 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " "); |
597 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu); | 595 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu); |
@@ -602,6 +600,25 @@ static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) | |||
602 | return i; | 600 | return i; |
603 | } | 601 | } |
604 | 602 | ||
603 | /** | ||
604 | * show_related_cpus - show the CPUs affected by each transition even if | ||
605 | * hw coordination is in use | ||
606 | */ | ||
607 | static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) | ||
608 | { | ||
609 | if (cpus_empty(policy->related_cpus)) | ||
610 | return show_cpus(policy->cpus, buf); | ||
611 | return show_cpus(policy->related_cpus, buf); | ||
612 | } | ||
613 | |||
614 | /** | ||
615 | * show_affected_cpus - show the CPUs affected by each transition | ||
616 | */ | ||
617 | static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) | ||
618 | { | ||
619 | return show_cpus(policy->cpus, buf); | ||
620 | } | ||
621 | |||
605 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, | 622 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, |
606 | const char *buf, size_t count) | 623 | const char *buf, size_t count) |
607 | { | 624 | { |
@@ -646,6 +663,7 @@ define_one_ro(cpuinfo_max_freq); | |||
646 | define_one_ro(scaling_available_governors); | 663 | define_one_ro(scaling_available_governors); |
647 | define_one_ro(scaling_driver); | 664 | define_one_ro(scaling_driver); |
648 | define_one_ro(scaling_cur_freq); | 665 | define_one_ro(scaling_cur_freq); |
666 | define_one_ro(related_cpus); | ||
649 | define_one_ro(affected_cpus); | 667 | define_one_ro(affected_cpus); |
650 | define_one_rw(scaling_min_freq); | 668 | define_one_rw(scaling_min_freq); |
651 | define_one_rw(scaling_max_freq); | 669 | define_one_rw(scaling_max_freq); |
@@ -658,6 +676,7 @@ static struct attribute *default_attrs[] = { | |||
658 | &scaling_min_freq.attr, | 676 | &scaling_min_freq.attr, |
659 | &scaling_max_freq.attr, | 677 | &scaling_max_freq.attr, |
660 | &affected_cpus.attr, | 678 | &affected_cpus.attr, |
679 | &related_cpus.attr, | ||
661 | &scaling_governor.attr, | 680 | &scaling_governor.attr, |
662 | &scaling_driver.attr, | 681 | &scaling_driver.attr, |
663 | &scaling_available_governors.attr, | 682 | &scaling_available_governors.attr, |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index ddd8652fc3f3..a881fd62c447 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -83,7 +83,8 @@ struct cpufreq_real_policy { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct cpufreq_policy { | 85 | struct cpufreq_policy { |
86 | cpumask_t cpus; /* affected CPUs */ | 86 | cpumask_t cpus; /* CPUs requiring sw coordination */ |
87 | cpumask_t related_cpus; /* CPUs with any coordination */ | ||
87 | unsigned int shared_type; /* ANY or ALL affected CPUs | 88 | unsigned int shared_type; /* ANY or ALL affected CPUs |
88 | should set cpufreq */ | 89 | should set cpufreq */ |
89 | unsigned int cpu; /* cpu nr of registered CPU */ | 90 | unsigned int cpu; /* cpu nr of registered CPU */ |