diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-18 00:00:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-18 00:00:02 -0400 |
commit | dcbf77b9e86e1726f5fbd01bb98820dac06d456e (patch) | |
tree | 2f0b728ce70c03e1d0e3461e8a3c3d1fbe68fb90 /arch | |
parent | ca043a66ae48c74fa628ec92178f7a54f5b9a106 (diff) | |
parent | 29cd8bae396583a2ee9a3340db8c5102acf9f6fd (diff) |
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (37 commits)
sched: Fix SD_POWERSAVING_BALANCE|SD_PREFER_LOCAL vs SD_WAKE_AFFINE
sched: Stop buddies from hogging the system
sched: Add new wakeup preemption mode: WAKEUP_RUNNING
sched: Fix TASK_WAKING & loadaverage breakage
sched: Disable wakeup balancing
sched: Rename flags to wake_flags
sched: Clean up the load_idx selection in select_task_rq_fair
sched: Optimize cgroup vs wakeup a bit
sched: x86: Name old_perf in a unique way
sched: Implement a gentler fair-sleepers feature
sched: Add SD_PREFER_LOCAL
sched: Add a few SYNC hint knobs to play with
sched: Fix sync wakeups again
sched: Add WF_FORK
sched: Rename sync arguments
sched: Rename select_task_rq() argument
sched: Feature to disable APERF/MPERF cpu_power
x86: sched: Provide arch implementations using aperf/mperf
x86: Add generic aperf/mperf code
x86: Move APERF/MPERF into a X86_FEATURE
...
Fix up trivial conflict in arch/x86/include/asm/processor.h due to
nearby addition of amd_get_nb_id() declaration from the EDAC merge.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/include/asm/topology.h | 17 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-ip27/topology.h | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/topology.h | 9 | ||||
-rw-r--r-- | arch/sh/include/asm/topology.h | 10 | ||||
-rw-r--r-- | arch/sparc/include/asm/topology_64.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/cpufeature.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/processor.h | 30 | ||||
-rw-r--r-- | arch/x86/include/asm/topology.h | 14 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 88 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/sched.c | 55 |
12 files changed, 129 insertions, 111 deletions
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h index 7b4c8c70b2d1..d0141fbf51d0 100644 --- a/arch/ia64/include/asm/topology.h +++ b/arch/ia64/include/asm/topology.h | |||
@@ -61,12 +61,13 @@ void build_cpu_to_node_map(void); | |||
61 | .cache_nice_tries = 2, \ | 61 | .cache_nice_tries = 2, \ |
62 | .busy_idx = 2, \ | 62 | .busy_idx = 2, \ |
63 | .idle_idx = 1, \ | 63 | .idle_idx = 1, \ |
64 | .newidle_idx = 2, \ | 64 | .newidle_idx = 0, \ |
65 | .wake_idx = 1, \ | 65 | .wake_idx = 0, \ |
66 | .forkexec_idx = 1, \ | 66 | .forkexec_idx = 0, \ |
67 | .flags = SD_LOAD_BALANCE \ | 67 | .flags = SD_LOAD_BALANCE \ |
68 | | SD_BALANCE_NEWIDLE \ | 68 | | SD_BALANCE_NEWIDLE \ |
69 | | SD_BALANCE_EXEC \ | 69 | | SD_BALANCE_EXEC \ |
70 | | SD_BALANCE_FORK \ | ||
70 | | SD_WAKE_AFFINE, \ | 71 | | SD_WAKE_AFFINE, \ |
71 | .last_balance = jiffies, \ | 72 | .last_balance = jiffies, \ |
72 | .balance_interval = 1, \ | 73 | .balance_interval = 1, \ |
@@ -85,14 +86,14 @@ void build_cpu_to_node_map(void); | |||
85 | .cache_nice_tries = 2, \ | 86 | .cache_nice_tries = 2, \ |
86 | .busy_idx = 3, \ | 87 | .busy_idx = 3, \ |
87 | .idle_idx = 2, \ | 88 | .idle_idx = 2, \ |
88 | .newidle_idx = 2, \ | 89 | .newidle_idx = 0, \ |
89 | .wake_idx = 1, \ | 90 | .wake_idx = 0, \ |
90 | .forkexec_idx = 1, \ | 91 | .forkexec_idx = 0, \ |
91 | .flags = SD_LOAD_BALANCE \ | 92 | .flags = SD_LOAD_BALANCE \ |
93 | | SD_BALANCE_NEWIDLE \ | ||
92 | | SD_BALANCE_EXEC \ | 94 | | SD_BALANCE_EXEC \ |
93 | | SD_BALANCE_FORK \ | 95 | | SD_BALANCE_FORK \ |
94 | | SD_SERIALIZE \ | 96 | | SD_SERIALIZE, \ |
95 | | SD_WAKE_BALANCE, \ | ||
96 | .last_balance = jiffies, \ | 97 | .last_balance = jiffies, \ |
97 | .balance_interval = 64, \ | 98 | .balance_interval = 64, \ |
98 | .nr_balance_failed = 0, \ | 99 | .nr_balance_failed = 0, \ |
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h index 07547231e078..230591707005 100644 --- a/arch/mips/include/asm/mach-ip27/topology.h +++ b/arch/mips/include/asm/mach-ip27/topology.h | |||
@@ -48,7 +48,6 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; | |||
48 | .cache_nice_tries = 1, \ | 48 | .cache_nice_tries = 1, \ |
49 | .flags = SD_LOAD_BALANCE \ | 49 | .flags = SD_LOAD_BALANCE \ |
50 | | SD_BALANCE_EXEC \ | 50 | | SD_BALANCE_EXEC \ |
51 | | SD_WAKE_BALANCE, \ | ||
52 | .last_balance = jiffies, \ | 51 | .last_balance = jiffies, \ |
53 | .balance_interval = 1, \ | 52 | .balance_interval = 1, \ |
54 | .nr_balance_failed = 0, \ | 53 | .nr_balance_failed = 0, \ |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 054a16d68082..394edcbcce71 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -57,14 +57,13 @@ static inline int pcibus_to_node(struct pci_bus *bus) | |||
57 | .cache_nice_tries = 1, \ | 57 | .cache_nice_tries = 1, \ |
58 | .busy_idx = 3, \ | 58 | .busy_idx = 3, \ |
59 | .idle_idx = 1, \ | 59 | .idle_idx = 1, \ |
60 | .newidle_idx = 2, \ | 60 | .newidle_idx = 0, \ |
61 | .wake_idx = 1, \ | 61 | .wake_idx = 0, \ |
62 | .flags = SD_LOAD_BALANCE \ | 62 | .flags = SD_LOAD_BALANCE \ |
63 | | SD_BALANCE_EXEC \ | 63 | | SD_BALANCE_EXEC \ |
64 | | SD_BALANCE_FORK \ | ||
64 | | SD_BALANCE_NEWIDLE \ | 65 | | SD_BALANCE_NEWIDLE \ |
65 | | SD_WAKE_IDLE \ | 66 | | SD_SERIALIZE, \ |
66 | | SD_SERIALIZE \ | ||
67 | | SD_WAKE_BALANCE, \ | ||
68 | .last_balance = jiffies, \ | 67 | .last_balance = jiffies, \ |
69 | .balance_interval = 1, \ | 68 | .balance_interval = 1, \ |
70 | .nr_balance_failed = 0, \ | 69 | .nr_balance_failed = 0, \ |
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h index b69ee850906d..f8c40cc65054 100644 --- a/arch/sh/include/asm/topology.h +++ b/arch/sh/include/asm/topology.h | |||
@@ -15,14 +15,14 @@ | |||
15 | .cache_nice_tries = 2, \ | 15 | .cache_nice_tries = 2, \ |
16 | .busy_idx = 3, \ | 16 | .busy_idx = 3, \ |
17 | .idle_idx = 2, \ | 17 | .idle_idx = 2, \ |
18 | .newidle_idx = 2, \ | 18 | .newidle_idx = 0, \ |
19 | .wake_idx = 1, \ | 19 | .wake_idx = 0, \ |
20 | .forkexec_idx = 1, \ | 20 | .forkexec_idx = 0, \ |
21 | .flags = SD_LOAD_BALANCE \ | 21 | .flags = SD_LOAD_BALANCE \ |
22 | | SD_BALANCE_FORK \ | 22 | | SD_BALANCE_FORK \ |
23 | | SD_BALANCE_EXEC \ | 23 | | SD_BALANCE_EXEC \ |
24 | | SD_SERIALIZE \ | 24 | | SD_BALANCE_NEWIDLE \ |
25 | | SD_WAKE_BALANCE, \ | 25 | | SD_SERIALIZE, \ |
26 | .last_balance = jiffies, \ | 26 | .last_balance = jiffies, \ |
27 | .balance_interval = 1, \ | 27 | .balance_interval = 1, \ |
28 | .nr_balance_failed = 0, \ | 28 | .nr_balance_failed = 0, \ |
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index e5ea8d332421..26cd25c08399 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h | |||
@@ -52,13 +52,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus) | |||
52 | .busy_idx = 3, \ | 52 | .busy_idx = 3, \ |
53 | .idle_idx = 2, \ | 53 | .idle_idx = 2, \ |
54 | .newidle_idx = 0, \ | 54 | .newidle_idx = 0, \ |
55 | .wake_idx = 1, \ | 55 | .wake_idx = 0, \ |
56 | .forkexec_idx = 1, \ | 56 | .forkexec_idx = 0, \ |
57 | .flags = SD_LOAD_BALANCE \ | 57 | .flags = SD_LOAD_BALANCE \ |
58 | | SD_BALANCE_FORK \ | 58 | | SD_BALANCE_FORK \ |
59 | | SD_BALANCE_EXEC \ | 59 | | SD_BALANCE_EXEC \ |
60 | | SD_SERIALIZE \ | 60 | | SD_SERIALIZE, \ |
61 | | SD_WAKE_BALANCE, \ | ||
62 | .last_balance = jiffies, \ | 61 | .last_balance = jiffies, \ |
63 | .balance_interval = 1, \ | 62 | .balance_interval = 1, \ |
64 | } | 63 | } |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 847fee6493a2..9cfc88b97742 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -96,6 +96,7 @@ | |||
96 | #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */ | 96 | #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */ |
97 | #define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */ | 97 | #define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */ |
98 | #define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */ | 98 | #define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */ |
99 | #define X86_FEATURE_APERFMPERF (3*32+28) /* APERFMPERF */ | ||
99 | 100 | ||
100 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | 101 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ |
101 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ | 102 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 42a3f936dadc..c3429e8b2424 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -27,6 +27,7 @@ struct mm_struct; | |||
27 | #include <linux/cpumask.h> | 27 | #include <linux/cpumask.h> |
28 | #include <linux/cache.h> | 28 | #include <linux/cache.h> |
29 | #include <linux/threads.h> | 29 | #include <linux/threads.h> |
30 | #include <linux/math64.h> | ||
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -1022,4 +1023,33 @@ extern int set_tsc_mode(unsigned int val); | |||
1022 | 1023 | ||
1023 | extern int amd_get_nb_id(int cpu); | 1024 | extern int amd_get_nb_id(int cpu); |
1024 | 1025 | ||
1026 | struct aperfmperf { | ||
1027 | u64 aperf, mperf; | ||
1028 | }; | ||
1029 | |||
1030 | static inline void get_aperfmperf(struct aperfmperf *am) | ||
1031 | { | ||
1032 | WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF)); | ||
1033 | |||
1034 | rdmsrl(MSR_IA32_APERF, am->aperf); | ||
1035 | rdmsrl(MSR_IA32_MPERF, am->mperf); | ||
1036 | } | ||
1037 | |||
1038 | #define APERFMPERF_SHIFT 10 | ||
1039 | |||
1040 | static inline | ||
1041 | unsigned long calc_aperfmperf_ratio(struct aperfmperf *old, | ||
1042 | struct aperfmperf *new) | ||
1043 | { | ||
1044 | u64 aperf = new->aperf - old->aperf; | ||
1045 | u64 mperf = new->mperf - old->mperf; | ||
1046 | unsigned long ratio = aperf; | ||
1047 | |||
1048 | mperf >>= APERFMPERF_SHIFT; | ||
1049 | if (mperf) | ||
1050 | ratio = div64_u64(aperf, mperf); | ||
1051 | |||
1052 | return ratio; | ||
1053 | } | ||
1054 | |||
1025 | #endif /* _ASM_X86_PROCESSOR_H */ | 1055 | #endif /* _ASM_X86_PROCESSOR_H */ |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 26d06e052a18..6f0695d744bf 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -116,15 +116,11 @@ extern unsigned long node_remap_size[]; | |||
116 | 116 | ||
117 | # define SD_CACHE_NICE_TRIES 1 | 117 | # define SD_CACHE_NICE_TRIES 1 |
118 | # define SD_IDLE_IDX 1 | 118 | # define SD_IDLE_IDX 1 |
119 | # define SD_NEWIDLE_IDX 2 | ||
120 | # define SD_FORKEXEC_IDX 0 | ||
121 | 119 | ||
122 | #else | 120 | #else |
123 | 121 | ||
124 | # define SD_CACHE_NICE_TRIES 2 | 122 | # define SD_CACHE_NICE_TRIES 2 |
125 | # define SD_IDLE_IDX 2 | 123 | # define SD_IDLE_IDX 2 |
126 | # define SD_NEWIDLE_IDX 2 | ||
127 | # define SD_FORKEXEC_IDX 1 | ||
128 | 124 | ||
129 | #endif | 125 | #endif |
130 | 126 | ||
@@ -137,22 +133,20 @@ extern unsigned long node_remap_size[]; | |||
137 | .cache_nice_tries = SD_CACHE_NICE_TRIES, \ | 133 | .cache_nice_tries = SD_CACHE_NICE_TRIES, \ |
138 | .busy_idx = 3, \ | 134 | .busy_idx = 3, \ |
139 | .idle_idx = SD_IDLE_IDX, \ | 135 | .idle_idx = SD_IDLE_IDX, \ |
140 | .newidle_idx = SD_NEWIDLE_IDX, \ | 136 | .newidle_idx = 0, \ |
141 | .wake_idx = 1, \ | 137 | .wake_idx = 0, \ |
142 | .forkexec_idx = SD_FORKEXEC_IDX, \ | 138 | .forkexec_idx = 0, \ |
143 | \ | 139 | \ |
144 | .flags = 1*SD_LOAD_BALANCE \ | 140 | .flags = 1*SD_LOAD_BALANCE \ |
145 | | 1*SD_BALANCE_NEWIDLE \ | 141 | | 1*SD_BALANCE_NEWIDLE \ |
146 | | 1*SD_BALANCE_EXEC \ | 142 | | 1*SD_BALANCE_EXEC \ |
147 | | 1*SD_BALANCE_FORK \ | 143 | | 1*SD_BALANCE_FORK \ |
148 | | 0*SD_WAKE_IDLE \ | 144 | | 0*SD_BALANCE_WAKE \ |
149 | | 1*SD_WAKE_AFFINE \ | 145 | | 1*SD_WAKE_AFFINE \ |
150 | | 1*SD_WAKE_BALANCE \ | ||
151 | | 0*SD_SHARE_CPUPOWER \ | 146 | | 0*SD_SHARE_CPUPOWER \ |
152 | | 0*SD_POWERSAVINGS_BALANCE \ | 147 | | 0*SD_POWERSAVINGS_BALANCE \ |
153 | | 0*SD_SHARE_PKG_RESOURCES \ | 148 | | 0*SD_SHARE_PKG_RESOURCES \ |
154 | | 1*SD_SERIALIZE \ | 149 | | 1*SD_SERIALIZE \ |
155 | | 1*SD_WAKE_IDLE_FAR \ | ||
156 | | 0*SD_PREFER_SIBLING \ | 150 | | 0*SD_PREFER_SIBLING \ |
157 | , \ | 151 | , \ |
158 | .last_balance = jiffies, \ | 152 | .last_balance = jiffies, \ |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index c1f253dac155..8dd30638fe44 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -13,7 +13,7 @@ CFLAGS_common.o := $(nostackp) | |||
13 | 13 | ||
14 | obj-y := intel_cacheinfo.o addon_cpuid_features.o | 14 | obj-y := intel_cacheinfo.o addon_cpuid_features.o |
15 | obj-y += proc.o capflags.o powerflags.o common.o | 15 | obj-y += proc.o capflags.o powerflags.o common.o |
16 | obj-y += vmware.o hypervisor.o | 16 | obj-y += vmware.o hypervisor.o sched.o |
17 | 17 | ||
18 | obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o | 18 | obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o |
19 | obj-$(CONFIG_X86_64) += bugs_64.o | 19 | obj-$(CONFIG_X86_64) += bugs_64.o |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index ae9b503220ca..4109679863c1 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -60,7 +60,6 @@ enum { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | #define INTEL_MSR_RANGE (0xffff) | 62 | #define INTEL_MSR_RANGE (0xffff) |
63 | #define CPUID_6_ECX_APERFMPERF_CAPABILITY (0x1) | ||
64 | 63 | ||
65 | struct acpi_cpufreq_data { | 64 | struct acpi_cpufreq_data { |
66 | struct acpi_processor_performance *acpi_data; | 65 | struct acpi_processor_performance *acpi_data; |
@@ -71,11 +70,7 @@ struct acpi_cpufreq_data { | |||
71 | 70 | ||
72 | static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); | 71 | static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); |
73 | 72 | ||
74 | struct acpi_msr_data { | 73 | static DEFINE_PER_CPU(struct aperfmperf, old_perf); |
75 | u64 saved_aperf, saved_mperf; | ||
76 | }; | ||
77 | |||
78 | static DEFINE_PER_CPU(struct acpi_msr_data, msr_data); | ||
79 | 74 | ||
80 | DEFINE_TRACE(power_mark); | 75 | DEFINE_TRACE(power_mark); |
81 | 76 | ||
@@ -244,23 +239,12 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
244 | return cmd.val; | 239 | return cmd.val; |
245 | } | 240 | } |
246 | 241 | ||
247 | struct perf_pair { | ||
248 | union { | ||
249 | struct { | ||
250 | u32 lo; | ||
251 | u32 hi; | ||
252 | } split; | ||
253 | u64 whole; | ||
254 | } aperf, mperf; | ||
255 | }; | ||
256 | |||
257 | /* Called via smp_call_function_single(), on the target CPU */ | 242 | /* Called via smp_call_function_single(), on the target CPU */ |
258 | static void read_measured_perf_ctrs(void *_cur) | 243 | static void read_measured_perf_ctrs(void *_cur) |
259 | { | 244 | { |
260 | struct perf_pair *cur = _cur; | 245 | struct aperfmperf *am = _cur; |
261 | 246 | ||
262 | rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi); | 247 | get_aperfmperf(am); |
263 | rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi); | ||
264 | } | 248 | } |
265 | 249 | ||
266 | /* | 250 | /* |
@@ -279,63 +263,17 @@ static void read_measured_perf_ctrs(void *_cur) | |||
279 | static unsigned int get_measured_perf(struct cpufreq_policy *policy, | 263 | static unsigned int get_measured_perf(struct cpufreq_policy *policy, |
280 | unsigned int cpu) | 264 | unsigned int cpu) |
281 | { | 265 | { |
282 | struct perf_pair readin, cur; | 266 | struct aperfmperf perf; |
283 | unsigned int perf_percent; | 267 | unsigned long ratio; |
284 | unsigned int retval; | 268 | unsigned int retval; |
285 | 269 | ||
286 | if (smp_call_function_single(cpu, read_measured_perf_ctrs, &readin, 1)) | 270 | if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1)) |
287 | return 0; | 271 | return 0; |
288 | 272 | ||
289 | cur.aperf.whole = readin.aperf.whole - | 273 | ratio = calc_aperfmperf_ratio(&per_cpu(old_perf, cpu), &perf); |
290 | per_cpu(msr_data, cpu).saved_aperf; | 274 | per_cpu(old_perf, cpu) = perf; |
291 | cur.mperf.whole = readin.mperf.whole - | ||
292 | per_cpu(msr_data, cpu).saved_mperf; | ||
293 | per_cpu(msr_data, cpu).saved_aperf = readin.aperf.whole; | ||
294 | per_cpu(msr_data, cpu).saved_mperf = readin.mperf.whole; | ||
295 | |||
296 | #ifdef __i386__ | ||
297 | /* | ||
298 | * We dont want to do 64 bit divide with 32 bit kernel | ||
299 | * Get an approximate value. Return failure in case we cannot get | ||
300 | * an approximate value. | ||
301 | */ | ||
302 | if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) { | ||
303 | int shift_count; | ||
304 | u32 h; | ||
305 | |||
306 | h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi); | ||
307 | shift_count = fls(h); | ||
308 | |||
309 | cur.aperf.whole >>= shift_count; | ||
310 | cur.mperf.whole >>= shift_count; | ||
311 | } | ||
312 | |||
313 | if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) { | ||
314 | int shift_count = 7; | ||
315 | cur.aperf.split.lo >>= shift_count; | ||
316 | cur.mperf.split.lo >>= shift_count; | ||
317 | } | ||
318 | |||
319 | if (cur.aperf.split.lo && cur.mperf.split.lo) | ||
320 | perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo; | ||
321 | else | ||
322 | perf_percent = 0; | ||
323 | 275 | ||
324 | #else | 276 | retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT; |
325 | if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) { | ||
326 | int shift_count = 7; | ||
327 | cur.aperf.whole >>= shift_count; | ||
328 | cur.mperf.whole >>= shift_count; | ||
329 | } | ||
330 | |||
331 | if (cur.aperf.whole && cur.mperf.whole) | ||
332 | perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole; | ||
333 | else | ||
334 | perf_percent = 0; | ||
335 | |||
336 | #endif | ||
337 | |||
338 | retval = (policy->cpuinfo.max_freq * perf_percent) / 100; | ||
339 | 277 | ||
340 | return retval; | 278 | return retval; |
341 | } | 279 | } |
@@ -731,12 +669,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
731 | acpi_processor_notify_smm(THIS_MODULE); | 669 | acpi_processor_notify_smm(THIS_MODULE); |
732 | 670 | ||
733 | /* Check for APERF/MPERF support in hardware */ | 671 | /* Check for APERF/MPERF support in hardware */ |
734 | if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) { | 672 | if (cpu_has(c, X86_FEATURE_APERFMPERF)) |
735 | unsigned int ecx; | 673 | acpi_cpufreq_driver.getavg = get_measured_perf; |
736 | ecx = cpuid_ecx(6); | ||
737 | if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY) | ||
738 | acpi_cpufreq_driver.getavg = get_measured_perf; | ||
739 | } | ||
740 | 674 | ||
741 | dprintk("CPU%u - ACPI performance management activated.\n", cpu); | 675 | dprintk("CPU%u - ACPI performance management activated.\n", cpu); |
742 | for (i = 0; i < perf->state_count; i++) | 676 | for (i = 0; i < perf->state_count; i++) |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 80a722a071b5..40e1835b35e8 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -350,6 +350,12 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
350 | set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); | 350 | set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); |
351 | } | 351 | } |
352 | 352 | ||
353 | if (c->cpuid_level > 6) { | ||
354 | unsigned ecx = cpuid_ecx(6); | ||
355 | if (ecx & 0x01) | ||
356 | set_cpu_cap(c, X86_FEATURE_APERFMPERF); | ||
357 | } | ||
358 | |||
353 | if (cpu_has_xmm2) | 359 | if (cpu_has_xmm2) |
354 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | 360 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); |
355 | if (cpu_has_ds) { | 361 | if (cpu_has_ds) { |
diff --git a/arch/x86/kernel/cpu/sched.c b/arch/x86/kernel/cpu/sched.c new file mode 100644 index 000000000000..a640ae5ad201 --- /dev/null +++ b/arch/x86/kernel/cpu/sched.c | |||
@@ -0,0 +1,55 @@ | |||
1 | #include <linux/sched.h> | ||
2 | #include <linux/math64.h> | ||
3 | #include <linux/percpu.h> | ||
4 | #include <linux/irqflags.h> | ||
5 | |||
6 | #include <asm/cpufeature.h> | ||
7 | #include <asm/processor.h> | ||
8 | |||
9 | #ifdef CONFIG_SMP | ||
10 | |||
11 | static DEFINE_PER_CPU(struct aperfmperf, old_perf_sched); | ||
12 | |||
13 | static unsigned long scale_aperfmperf(void) | ||
14 | { | ||
15 | struct aperfmperf val, *old = &__get_cpu_var(old_perf_sched); | ||
16 | unsigned long ratio, flags; | ||
17 | |||
18 | local_irq_save(flags); | ||
19 | get_aperfmperf(&val); | ||
20 | local_irq_restore(flags); | ||
21 | |||
22 | ratio = calc_aperfmperf_ratio(old, &val); | ||
23 | *old = val; | ||
24 | |||
25 | return ratio; | ||
26 | } | ||
27 | |||
28 | unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu) | ||
29 | { | ||
30 | /* | ||
31 | * do aperf/mperf on the cpu level because it includes things | ||
32 | * like turbo mode, which are relevant to full cores. | ||
33 | */ | ||
34 | if (boot_cpu_has(X86_FEATURE_APERFMPERF)) | ||
35 | return scale_aperfmperf(); | ||
36 | |||
37 | /* | ||
38 | * maybe have something cpufreq here | ||
39 | */ | ||
40 | |||
41 | return default_scale_freq_power(sd, cpu); | ||
42 | } | ||
43 | |||
44 | unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu) | ||
45 | { | ||
46 | /* | ||
47 | * aperf/mperf already includes the smt gain | ||
48 | */ | ||
49 | if (boot_cpu_has(X86_FEATURE_APERFMPERF)) | ||
50 | return SCHED_LOAD_SCALE; | ||
51 | |||
52 | return default_scale_smt_power(sd, cpu); | ||
53 | } | ||
54 | |||
55 | #endif | ||