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 | |
| 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>
| -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 | ||
