aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPekka Paalanen <pq@iki.fi>2008-05-12 15:21:02 -0400
committerThomas Gleixner <tglx@linutronix.de>2008-05-24 05:26:52 -0400
commit7423d1115f18627666d475fccc7c62394406ff8c (patch)
tree0c53cab24435ee95c0f4b01e257060bc171c15b6 /arch
parent37b3619257d3190f47f233d7ed626d4b9916462c (diff)
x86 mmiotrace: dynamically disable non-boot CPUs
From 8979ee55cb6a429c4edd72ebec2244b849f6a79a Mon Sep 17 00:00:00 2001 From: Pekka Paalanen <pq@iki.fi> Date: Sat, 12 Apr 2008 00:18:57 +0300 Mmiotrace is not reliable with multiple CPUs and may miss events. Drop to single CPU when mmiotrace is activated. Signed-off-by: Pekka Paalanen <pq@iki.fi> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/mm/mmio-mod.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 6d6cac84c045..1f77d8532037 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -32,6 +32,7 @@
32#include <asm/e820.h> /* for ISA_START_ADDRESS */ 32#include <asm/e820.h> /* for ISA_START_ADDRESS */
33#include <asm/atomic.h> 33#include <asm/atomic.h>
34#include <linux/percpu.h> 34#include <linux/percpu.h>
35#include <linux/cpu.h>
35 36
36#include "pf_in.h" 37#include "pf_in.h"
37 38
@@ -400,6 +401,64 @@ static void clear_trace_list(void)
400 } 401 }
401} 402}
402 403
404#ifdef CONFIG_HOTPLUG_CPU
405static cpumask_t downed_cpus;
406
407static void enter_uniprocessor(void)
408{
409 int cpu;
410 int err;
411
412 get_online_cpus();
413 downed_cpus = cpu_online_map;
414 cpu_clear(first_cpu(cpu_online_map), downed_cpus);
415 if (num_online_cpus() > 1)
416 pr_notice(NAME "Disabling non-boot CPUs...\n");
417 put_online_cpus();
418
419 for_each_cpu_mask(cpu, downed_cpus) {
420 err = cpu_down(cpu);
421 if (!err) {
422 pr_info(NAME "CPU%d is down.\n", cpu);
423 } else {
424 pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err);
425 }
426 }
427 if (num_online_cpus() > 1)
428 pr_warning(NAME "multiple CPUs still online, "
429 "may miss events.\n");
430}
431
432static void leave_uniprocessor(void)
433{
434 int cpu;
435 int err;
436
437 if (cpus_weight(downed_cpus) == 0)
438 return;
439 pr_notice(NAME "Re-enabling CPUs...\n");
440 for_each_cpu_mask(cpu, downed_cpus) {
441 err = cpu_up(cpu);
442 if (!err)
443 pr_info(NAME "enabled CPU%d.\n", cpu);
444 else
445 pr_err(NAME "cannot re-enable CPU%d: %d\n", cpu, err);
446 }
447}
448
449#else /* !CONFIG_HOTPLUG_CPU */
450static void enter_uniprocessor(void)
451{
452 if (num_online_cpus() > 1)
453 pr_warning(NAME "multiple CPUs are online, may miss events. "
454 "Suggest booting with maxcpus=1 kernel argument.\n");
455}
456
457static void leave_uniprocessor(void)
458{
459}
460#endif
461
403#if 0 /* XXX: out of order */ 462#if 0 /* XXX: out of order */
404static struct file_operations fops_marker = { 463static struct file_operations fops_marker = {
405 .owner = THIS_MODULE, 464 .owner = THIS_MODULE,
@@ -422,6 +481,7 @@ void enable_mmiotrace(void)
422 481
423 if (nommiotrace) 482 if (nommiotrace)
424 pr_info(NAME "MMIO tracing disabled.\n"); 483 pr_info(NAME "MMIO tracing disabled.\n");
484 enter_uniprocessor();
425 spin_lock_irq(&trace_lock); 485 spin_lock_irq(&trace_lock);
426 atomic_inc(&mmiotrace_enabled); 486 atomic_inc(&mmiotrace_enabled);
427 spin_unlock_irq(&trace_lock); 487 spin_unlock_irq(&trace_lock);
@@ -442,6 +502,7 @@ void disable_mmiotrace(void)
442 spin_unlock_irq(&trace_lock); 502 spin_unlock_irq(&trace_lock);
443 503
444 clear_trace_list(); /* guarantees: no more kmmio callbacks */ 504 clear_trace_list(); /* guarantees: no more kmmio callbacks */
505 leave_uniprocessor();
445 if (marker_file) { 506 if (marker_file) {
446 debugfs_remove(marker_file); 507 debugfs_remove(marker_file);
447 marker_file = NULL; 508 marker_file = NULL;