aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAndrew Morton <akpm@linux-foundation.org>2009-04-13 13:27:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 14:09:46 -0400
commit01599fca6758d2cd133e78f87426fc851c9ea725 (patch)
tree26a3f1d69c955de2c5388e5855dfe4ff3ff8687b /arch
parent8371f87c9994d9942af5984309835aeb948ba579 (diff)
cpufreq: use smp_call_function_[single|many]() in acpi-cpufreq.c
Atttempting to rid us of the problematic work_on_cpu(). Just use smp_call_fuction_single() here. This repairs a 10% sysbench(oltp)+mysql regression which Mike reported, due to commit 6b44003e5ca66a3fffeb5bc90f40ada2c4340896 Author: Andrew Morton <akpm@linux-foundation.org> Date: Thu Apr 9 09:50:37 2009 -0600 work_on_cpu(): rewrite it to create a kernel thread on demand It seems that the kernel calls these acpi-cpufreq functions at a quite high frequency. Valdis Kletnieks also reports that this causes 70-90 forks per second on his hardware. Cc: Valdis.Kletnieks@vt.edu Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Cc: Len Brown <len.brown@intel.com> Cc: Zhao Yakui <yakui.zhao@intel.com> Acked-by: Dave Jones <davej@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Tested-by: Mike Galbraith <efault@gmx.de> Cc: "Zhang, Yanmin" <yanmin_zhang@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Ingo Molnar <mingo@elte.hu> [ Made it use smp_call_function_many() instead of looping over cpu's with smp_call_function_single() - Linus ] Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 9d3af380c6bd..3e3cd3db7a0c 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -153,7 +153,8 @@ struct drv_cmd {
153 u32 val; 153 u32 val;
154}; 154};
155 155
156static long do_drv_read(void *_cmd) 156/* Called via smp_call_function_single(), on the target CPU */
157static void do_drv_read(void *_cmd)
157{ 158{
158 struct drv_cmd *cmd = _cmd; 159 struct drv_cmd *cmd = _cmd;
159 u32 h; 160 u32 h;
@@ -170,10 +171,10 @@ static long do_drv_read(void *_cmd)
170 default: 171 default:
171 break; 172 break;
172 } 173 }
173 return 0;
174} 174}
175 175
176static long do_drv_write(void *_cmd) 176/* Called via smp_call_function_many(), on the target CPUs */
177static void do_drv_write(void *_cmd)
177{ 178{
178 struct drv_cmd *cmd = _cmd; 179 struct drv_cmd *cmd = _cmd;
179 u32 lo, hi; 180 u32 lo, hi;
@@ -192,23 +193,18 @@ static long do_drv_write(void *_cmd)
192 default: 193 default:
193 break; 194 break;
194 } 195 }
195 return 0;
196} 196}
197 197
198static void drv_read(struct drv_cmd *cmd) 198static void drv_read(struct drv_cmd *cmd)
199{ 199{
200 cmd->val = 0; 200 cmd->val = 0;
201 201
202 work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd); 202 smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1);
203} 203}
204 204
205static void drv_write(struct drv_cmd *cmd) 205static void drv_write(struct drv_cmd *cmd)
206{ 206{
207 unsigned int i; 207 smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
208
209 for_each_cpu(i, cmd->mask) {
210 work_on_cpu(i, do_drv_write, cmd);
211 }
212} 208}
213 209
214static u32 get_cur_val(const struct cpumask *mask) 210static u32 get_cur_val(const struct cpumask *mask)
@@ -252,15 +248,13 @@ struct perf_pair {
252 } aperf, mperf; 248 } aperf, mperf;
253}; 249};
254 250
255 251/* Called via smp_call_function_single(), on the target CPU */
256static long read_measured_perf_ctrs(void *_cur) 252static void read_measured_perf_ctrs(void *_cur)
257{ 253{
258 struct perf_pair *cur = _cur; 254 struct perf_pair *cur = _cur;
259 255
260 rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi); 256 rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi);
261 rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi); 257 rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi);
262
263 return 0;
264} 258}
265 259
266/* 260/*
@@ -283,7 +277,7 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy,
283 unsigned int perf_percent; 277 unsigned int perf_percent;
284 unsigned int retval; 278 unsigned int retval;
285 279
286 if (!work_on_cpu(cpu, read_measured_perf_ctrs, &readin)) 280 if (smp_call_function_single(cpu, read_measured_perf_ctrs, &cur, 1))
287 return 0; 281 return 0;
288 282
289 cur.aperf.whole = readin.aperf.whole - 283 cur.aperf.whole = readin.aperf.whole -