Commit a1465d2f authored by Daniel Thompson's avatar Daniel Thompson Committed by Jason Wessel

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: default avatarDaniel Thompson <daniel.thompson@linaro.org>
Cc: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarJason Wessel <jason.wessel@windriver.com>
parent b8017177
...@@ -471,6 +471,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, ...@@ -471,6 +471,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
int cpu; int cpu;
int trace_on = 0; int trace_on = 0;
int online_cpus = num_online_cpus(); int online_cpus = num_online_cpus();
u64 time_left;
kgdb_info[ks->cpu].enter_kgdb++; kgdb_info[ks->cpu].enter_kgdb++;
kgdb_info[ks->cpu].exception_state |= exception_state; kgdb_info[ks->cpu].exception_state |= exception_state;
...@@ -595,9 +596,13 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, ...@@ -595,9 +596,13 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
/* /*
* Wait for the other CPUs to be notified and be waiting for us: * Wait for the other CPUs to be notified and be waiting for us:
*/ */
while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + time_left = loops_per_jiffy * HZ;
atomic_read(&slaves_in_kgdb)) != online_cpus) while (kgdb_do_roundup && --time_left &&
(atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) !=
online_cpus)
cpu_relax(); cpu_relax();
if (!time_left)
pr_crit("KGDB: Timed out waiting for secondary CPUs.\n");
/* /*
* At this point the primary processor is completely * At this point the primary processor is completely
......
...@@ -129,6 +129,10 @@ int kdb_stub(struct kgdb_state *ks) ...@@ -129,6 +129,10 @@ int kdb_stub(struct kgdb_state *ks)
ks->pass_exception = 1; ks->pass_exception = 1;
KDB_FLAG_SET(CATASTROPHIC); KDB_FLAG_SET(CATASTROPHIC);
} }
/* set CATASTROPHIC if the system contains unresponsive processors */
for_each_online_cpu(i)
if (!kgdb_info[i].enter_kgdb)
KDB_FLAG_SET(CATASTROPHIC);
if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) {
KDB_STATE_CLEAR(SSBPT); KDB_STATE_CLEAR(SSBPT);
KDB_STATE_CLEAR(DOING_SS); KDB_STATE_CLEAR(DOING_SS);
......
...@@ -2201,6 +2201,8 @@ static void kdb_cpu_status(void) ...@@ -2201,6 +2201,8 @@ static void kdb_cpu_status(void)
for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { for (start_cpu = -1, i = 0; i < NR_CPUS; i++) {
if (!cpu_online(i)) { if (!cpu_online(i)) {
state = 'F'; /* cpu is offline */ state = 'F'; /* cpu is offline */
} else if (!kgdb_info[i].enter_kgdb) {
state = 'D'; /* cpu is online but unresponsive */
} else { } else {
state = ' '; /* cpu is responding to kdb */ state = ' '; /* cpu is responding to kdb */
if (kdb_task_state_char(KDB_TSK(i)) == 'I') if (kdb_task_state_char(KDB_TSK(i)) == 'I')
...@@ -2254,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv) ...@@ -2254,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv)
/* /*
* Validate cpunum * Validate cpunum
*/ */
if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb)
return KDB_BADCPUNUM; return KDB_BADCPUNUM;
dbg_switch_cpu = cpunum; dbg_switch_cpu = cpunum;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment