aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/debug
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2014-11-11 10:31:53 -0500
committerJason Wessel <jason.wessel@windriver.com>2014-11-11 10:31:53 -0500
commita1465d2f396e416a0049332b20fca5977384b9f5 (patch)
tree6f8d42833a2f4d06a047d75cca5209d28b7c5986 /kernel/debug
parentb8017177cdfd46b0222b3b74b206780f52f22f3d (diff)
kgdb: timeout if secondary CPUs ignore the roundup
Currently if an active CPU fails to respond to a roundup request the CPU that requested the roundup will become stuck. This needlessly reduces the robustness of the debugger. This patch introduces a timeout allowing the system state to be examined even when the system contains unresponsive processors. It also modifies kdb's cpu command to make it censor attempts to switch to unresponsive processors and to report their state as (D)ead. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'kernel/debug')
-rw-r--r--kernel/debug/debug_core.c9
-rw-r--r--kernel/debug/kdb/kdb_debugger.c4
-rw-r--r--kernel/debug/kdb/kdb_main.c4
3 files changed, 14 insertions, 3 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 1adf62b39b96..acd749736822 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -471,6 +471,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
471 int cpu; 471 int cpu;
472 int trace_on = 0; 472 int trace_on = 0;
473 int online_cpus = num_online_cpus(); 473 int online_cpus = num_online_cpus();
474 u64 time_left;
474 475
475 kgdb_info[ks->cpu].enter_kgdb++; 476 kgdb_info[ks->cpu].enter_kgdb++;
476 kgdb_info[ks->cpu].exception_state |= exception_state; 477 kgdb_info[ks->cpu].exception_state |= exception_state;
@@ -595,9 +596,13 @@ return_normal:
595 /* 596 /*
596 * Wait for the other CPUs to be notified and be waiting for us: 597 * Wait for the other CPUs to be notified and be waiting for us:
597 */ 598 */
598 while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + 599 time_left = loops_per_jiffy * HZ;
599 atomic_read(&slaves_in_kgdb)) != online_cpus) 600 while (kgdb_do_roundup && --time_left &&
601 (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) !=
602 online_cpus)
600 cpu_relax(); 603 cpu_relax();
604 if (!time_left)
605 pr_crit("KGDB: Timed out waiting for secondary CPUs.\n");
601 606
602 /* 607 /*
603 * At this point the primary processor is completely 608 * At this point the primary processor is completely
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c
index 8859ca34dcfe..15e1a7af5dd0 100644
--- a/kernel/debug/kdb/kdb_debugger.c
+++ b/kernel/debug/kdb/kdb_debugger.c
@@ -129,6 +129,10 @@ int kdb_stub(struct kgdb_state *ks)
129 ks->pass_exception = 1; 129 ks->pass_exception = 1;
130 KDB_FLAG_SET(CATASTROPHIC); 130 KDB_FLAG_SET(CATASTROPHIC);
131 } 131 }
132 /* set CATASTROPHIC if the system contains unresponsive processors */
133 for_each_online_cpu(i)
134 if (!kgdb_info[i].enter_kgdb)
135 KDB_FLAG_SET(CATASTROPHIC);
132 if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { 136 if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) {
133 KDB_STATE_CLEAR(SSBPT); 137 KDB_STATE_CLEAR(SSBPT);
134 KDB_STATE_CLEAR(DOING_SS); 138 KDB_STATE_CLEAR(DOING_SS);
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 8d84979cbe05..f191bddf64b8 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -2201,6 +2201,8 @@ static void kdb_cpu_status(void)
2201 for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { 2201 for (start_cpu = -1, i = 0; i < NR_CPUS; i++) {
2202 if (!cpu_online(i)) { 2202 if (!cpu_online(i)) {
2203 state = 'F'; /* cpu is offline */ 2203 state = 'F'; /* cpu is offline */
2204 } else if (!kgdb_info[i].enter_kgdb) {
2205 state = 'D'; /* cpu is online but unresponsive */
2204 } else { 2206 } else {
2205 state = ' '; /* cpu is responding to kdb */ 2207 state = ' '; /* cpu is responding to kdb */
2206 if (kdb_task_state_char(KDB_TSK(i)) == 'I') 2208 if (kdb_task_state_char(KDB_TSK(i)) == 'I')
@@ -2254,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv)
2254 /* 2256 /*
2255 * Validate cpunum 2257 * Validate cpunum
2256 */ 2258 */
2257 if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) 2259 if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb)
2258 return KDB_BADCPUNUM; 2260 return KDB_BADCPUNUM;
2259 2261
2260 dbg_switch_cpu = cpunum; 2262 dbg_switch_cpu = cpunum;