diff options
author | Pekka Paalanen <pq@iki.fi> | 2008-05-12 15:20:57 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-24 05:22:01 -0400 |
commit | f513638030ca384b0bace4df64f0b82f6ae1e4c6 (patch) | |
tree | 7f766aa7339528bcce42b26fd463c5d5ef89f990 /arch/x86/kernel/mmiotrace/kmmio.c | |
parent | 10c43d2eb50c9a5ad60388b9d3c41c31150049e6 (diff) |
x86 mmiotrace: Use percpu instead of arrays.
Signed-off-by: Pekka Paalanen <pq@iki.fi>
Cc: Eric Dumazet <dada1@cosmosbay.com>
Cc: pq@iki.fi
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/mmiotrace/kmmio.c')
-rw-r--r-- | arch/x86/kernel/mmiotrace/kmmio.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index e759f7c3878f..5e239d0b8467 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/preempt.h> | 18 | #include <linux/preempt.h> |
19 | #include <linux/percpu.h> | ||
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
20 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
21 | #include <asm/errno.h> | 22 | #include <asm/errno.h> |
@@ -49,7 +50,8 @@ static unsigned int handler_registered; | |||
49 | static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; | 50 | static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; |
50 | static LIST_HEAD(kmmio_probes); | 51 | static LIST_HEAD(kmmio_probes); |
51 | 52 | ||
52 | static struct kmmio_context kmmio_ctx[NR_CPUS]; | 53 | /* Accessed per-cpu */ |
54 | static DEFINE_PER_CPU(struct kmmio_context, kmmio_ctx); | ||
53 | 55 | ||
54 | static struct notifier_block nb_die = { | 56 | static struct notifier_block nb_die = { |
55 | .notifier_call = kmmio_die_notifier | 57 | .notifier_call = kmmio_die_notifier |
@@ -173,8 +175,7 @@ static void disarm_kmmio_fault_page(unsigned long page, int *page_level) | |||
173 | */ | 175 | */ |
174 | static int kmmio_handler(struct pt_regs *regs, unsigned long addr) | 176 | static int kmmio_handler(struct pt_regs *regs, unsigned long addr) |
175 | { | 177 | { |
176 | struct kmmio_context *ctx; | 178 | struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); |
177 | int cpu; | ||
178 | 179 | ||
179 | /* | 180 | /* |
180 | * Preemption is now disabled to prevent process switch during | 181 | * Preemption is now disabled to prevent process switch during |
@@ -187,8 +188,6 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) | |||
187 | * And that interrupt triggers a kmmio trap? | 188 | * And that interrupt triggers a kmmio trap? |
188 | */ | 189 | */ |
189 | preempt_disable(); | 190 | preempt_disable(); |
190 | cpu = smp_processor_id(); | ||
191 | ctx = &kmmio_ctx[cpu]; | ||
192 | 191 | ||
193 | /* interrupts disabled and CPU-local data => atomicity guaranteed. */ | 192 | /* interrupts disabled and CPU-local data => atomicity guaranteed. */ |
194 | if (ctx->active) { | 193 | if (ctx->active) { |
@@ -199,7 +198,7 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) | |||
199 | */ | 198 | */ |
200 | printk(KERN_EMERG "mmiotrace: recursive probe hit on CPU %d, " | 199 | printk(KERN_EMERG "mmiotrace: recursive probe hit on CPU %d, " |
201 | "for address %lu. Ignoring.\n", | 200 | "for address %lu. Ignoring.\n", |
202 | cpu, addr); | 201 | smp_processor_id(), addr); |
203 | goto no_kmmio; | 202 | goto no_kmmio; |
204 | } | 203 | } |
205 | ctx->active++; | 204 | ctx->active++; |
@@ -231,6 +230,7 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) | |||
231 | /* We hold lock, now we set present bit in PTE and single step. */ | 230 | /* We hold lock, now we set present bit in PTE and single step. */ |
232 | disarm_kmmio_fault_page(ctx->fpage->page, NULL); | 231 | disarm_kmmio_fault_page(ctx->fpage->page, NULL); |
233 | 232 | ||
233 | put_cpu_var(kmmio_ctx); | ||
234 | return 1; | 234 | return 1; |
235 | 235 | ||
236 | no_kmmio_locked: | 236 | no_kmmio_locked: |
@@ -238,6 +238,7 @@ no_kmmio_locked: | |||
238 | ctx->active--; | 238 | ctx->active--; |
239 | no_kmmio: | 239 | no_kmmio: |
240 | preempt_enable_no_resched(); | 240 | preempt_enable_no_resched(); |
241 | put_cpu_var(kmmio_ctx); | ||
241 | /* page fault not handled by kmmio */ | 242 | /* page fault not handled by kmmio */ |
242 | return 0; | 243 | return 0; |
243 | } | 244 | } |
@@ -249,11 +250,11 @@ no_kmmio: | |||
249 | */ | 250 | */ |
250 | static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) | 251 | static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) |
251 | { | 252 | { |
252 | int cpu = smp_processor_id(); | 253 | int ret = 0; |
253 | struct kmmio_context *ctx = &kmmio_ctx[cpu]; | 254 | struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); |
254 | 255 | ||
255 | if (!ctx->active) | 256 | if (!ctx->active) |
256 | return 0; | 257 | goto out; |
257 | 258 | ||
258 | if (ctx->probe && ctx->probe->post_handler) | 259 | if (ctx->probe && ctx->probe->post_handler) |
259 | ctx->probe->post_handler(ctx->probe, condition, regs); | 260 | ctx->probe->post_handler(ctx->probe, condition, regs); |
@@ -273,10 +274,12 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) | |||
273 | * will have TF set, in which case, continue the remaining processing | 274 | * will have TF set, in which case, continue the remaining processing |
274 | * of do_debug, as if this is not a probe hit. | 275 | * of do_debug, as if this is not a probe hit. |
275 | */ | 276 | */ |
276 | if (regs->flags & TF_MASK) | 277 | if (!(regs->flags & TF_MASK)) |
277 | return 0; | 278 | ret = 1; |
278 | 279 | ||
279 | return 1; | 280 | out: |
281 | put_cpu_var(kmmio_ctx); | ||
282 | return ret; | ||
280 | } | 283 | } |
281 | 284 | ||
282 | static int add_kmmio_fault_page(unsigned long page) | 285 | static int add_kmmio_fault_page(unsigned long page) |