aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>2014-03-10 16:35:21 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-20 08:43:41 -0400
commitc5929bd3a9920432dfb485253c64163fdfc90faf (patch)
tree088ea4025650fbfbff3013e341ca30d61585ce5c /arch/arm
parentf2e48a89053dea259d7f96cf0fd1cfc7c4b34d80 (diff)
arm, hw-breakpoint: Fix CPU hotplug callback registration
Subsystems that want to register CPU hotplug callbacks, as well as perform initialization for the CPUs that are already online, often do it as shown below: get_online_cpus(); for_each_online_cpu(cpu) init_cpu(cpu); register_cpu_notifier(&foobar_cpu_notifier); put_online_cpus(); This is wrong, since it is prone to ABBA deadlocks involving the cpu_add_remove_lock and the cpu_hotplug.lock (when running concurrently with CPU hotplug operations). Instead, the correct and race-free way of performing the callback registration is: cpu_notifier_register_begin(); for_each_online_cpu(cpu) init_cpu(cpu); /* Note the use of the double underscored version of the API */ __register_cpu_notifier(&foobar_cpu_notifier); cpu_notifier_register_done(); Fix the hw-breakpoint code in arm by using this latter form of callback registration. Cc: Russell King <linux@arm.linux.org.uk> Cc: Ingo Molnar <mingo@kernel.org> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/hw_breakpoint.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 3d446605cbf8..3702de8ab9b9 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -1072,6 +1072,8 @@ static int __init arch_hw_breakpoint_init(void)
1072 core_num_brps = get_num_brps(); 1072 core_num_brps = get_num_brps();
1073 core_num_wrps = get_num_wrps(); 1073 core_num_wrps = get_num_wrps();
1074 1074
1075 cpu_notifier_register_begin();
1076
1075 /* 1077 /*
1076 * We need to tread carefully here because DBGSWENABLE may be 1078 * We need to tread carefully here because DBGSWENABLE may be
1077 * driven low on this core and there isn't an architected way to 1079 * driven low on this core and there isn't an architected way to
@@ -1088,6 +1090,7 @@ static int __init arch_hw_breakpoint_init(void)
1088 if (!cpumask_empty(&debug_err_mask)) { 1090 if (!cpumask_empty(&debug_err_mask)) {
1089 core_num_brps = 0; 1091 core_num_brps = 0;
1090 core_num_wrps = 0; 1092 core_num_wrps = 0;
1093 cpu_notifier_register_done();
1091 return 0; 1094 return 0;
1092 } 1095 }
1093 1096
@@ -1107,7 +1110,10 @@ static int __init arch_hw_breakpoint_init(void)
1107 TRAP_HWBKPT, "breakpoint debug exception"); 1110 TRAP_HWBKPT, "breakpoint debug exception");
1108 1111
1109 /* Register hotplug and PM notifiers. */ 1112 /* Register hotplug and PM notifiers. */
1110 register_cpu_notifier(&dbg_reset_nb); 1113 __register_cpu_notifier(&dbg_reset_nb);
1114
1115 cpu_notifier_register_done();
1116
1111 pm_init(); 1117 pm_init();
1112 return 0; 1118 return 0;
1113} 1119}