diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2009-03-11 08:20:05 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-23 22:47:27 -0400 |
commit | 9a3719341a9b5d2f5a2e590497346b61cf3462a5 (patch) | |
tree | f9e34b1ab0afea5c867a829cfeb7e6291a4ffc64 /arch/powerpc/kernel/sysfs.c | |
parent | c5785f9e1c1c07c791fdc471f5c7fda4a5855b0c (diff) |
powerpc: Make sysfs code use smp_call_function_single
Impact: performance improvement
This fixes 'powerpc: avoid cpumask games in arch/powerpc/kernel/sysfs.c'
which talked about using smp_call_function_single, but actually used
work_on_cpu (an older version of the patch).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/sysfs.c')
-rw-r--r-- | arch/powerpc/kernel/sysfs.c | 31 |
1 files changed, 6 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 4a2ee08af6a7..e6cd6c990c25 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -134,36 +134,16 @@ void ppc_enable_pmcs(void) | |||
134 | } | 134 | } |
135 | EXPORT_SYMBOL(ppc_enable_pmcs); | 135 | EXPORT_SYMBOL(ppc_enable_pmcs); |
136 | 136 | ||
137 | #if defined(CONFIG_6xx) || defined(CONFIG_PPC64) | ||
138 | /* XXX convert to rusty's on_one_cpu */ | ||
139 | static unsigned long run_on_cpu(unsigned long cpu, | ||
140 | unsigned long (*func)(unsigned long), | ||
141 | unsigned long arg) | ||
142 | { | ||
143 | cpumask_t old_affinity = current->cpus_allowed; | ||
144 | unsigned long ret; | ||
145 | |||
146 | /* should return -EINVAL to userspace */ | ||
147 | if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) | ||
148 | return 0; | ||
149 | |||
150 | ret = func(arg); | ||
151 | |||
152 | set_cpus_allowed(current, old_affinity); | ||
153 | |||
154 | return ret; | ||
155 | } | ||
156 | #endif | ||
157 | 137 | ||
158 | #define SYSFS_PMCSETUP(NAME, ADDRESS) \ | 138 | #define SYSFS_PMCSETUP(NAME, ADDRESS) \ |
159 | static unsigned long read_##NAME(unsigned long junk) \ | 139 | static void read_##NAME(void *val) \ |
160 | { \ | 140 | { \ |
161 | return mfspr(ADDRESS); \ | 141 | mtspr(ADDRESS, *(unsigned long *)val); \ |
162 | } \ | 142 | } \ |
163 | static unsigned long write_##NAME(unsigned long val) \ | 143 | static unsigned long write_##NAME(unsigned long val) \ |
164 | { \ | 144 | { \ |
165 | ppc_enable_pmcs(); \ | 145 | ppc_enable_pmcs(); \ |
166 | mtspr(ADDRESS, val); \ | 146 | mtspr(ADDRESS, *(unsigned long *)val); \ |
167 | return 0; \ | 147 | return 0; \ |
168 | } \ | 148 | } \ |
169 | static ssize_t show_##NAME(struct sys_device *dev, \ | 149 | static ssize_t show_##NAME(struct sys_device *dev, \ |
@@ -171,7 +151,8 @@ static ssize_t show_##NAME(struct sys_device *dev, \ | |||
171 | char *buf) \ | 151 | char *buf) \ |
172 | { \ | 152 | { \ |
173 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ | 153 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ |
174 | unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ | 154 | unsigned long val; \ |
155 | smp_call_function_single(cpu->sysdev.id, read_##NAME, &val, 1); \ | ||
175 | return sprintf(buf, "%lx\n", val); \ | 156 | return sprintf(buf, "%lx\n", val); \ |
176 | } \ | 157 | } \ |
177 | static ssize_t __used \ | 158 | static ssize_t __used \ |
@@ -183,7 +164,7 @@ static ssize_t __used \ | |||
183 | int ret = sscanf(buf, "%lx", &val); \ | 164 | int ret = sscanf(buf, "%lx", &val); \ |
184 | if (ret != 1) \ | 165 | if (ret != 1) \ |
185 | return -EINVAL; \ | 166 | return -EINVAL; \ |
186 | run_on_cpu(cpu->sysdev.id, write_##NAME, val); \ | 167 | smp_call_function_single(cpu->sysdev.id, write_##NAME, &val, 1); \ |
187 | return count; \ | 168 | return count; \ |
188 | } | 169 | } |
189 | 170 | ||