Signed-off-by: Jason Wessel --- kernel/kgdb.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) --- a/kernel/kgdb.c +++ b/kernel/kgdb.c @@ -121,6 +121,7 @@ struct task_struct *kgdb_usethread, *kgd int debugger_step; atomic_t debugger_active; +static atomic_t kgdb_sync = ATOMIC_INIT(-1); /* Our I/O buffers. */ static char remcom_in_buffer[BUFMAX]; @@ -638,8 +639,14 @@ static void kgdb_wait(struct pt_regs *re kgdb_info[processor].task = current; atomic_set(&procindebug[processor], 1); + /* The master processor must be active to enter here, but this is + * gaurd in case the master processor had not been selected if + * this was an entry via nmi. + */ + while (!atomic_read(&debugger_active)); + /* Wait till master processor goes completely into the debugger. - * FIXME: this looks racy */ + */ while (!atomic_read(&procindebug[atomic_read(&debugger_active) - 1])) { int i = 10; /* an arbitrary number */ @@ -973,8 +980,13 @@ int kgdb_handle_exception(int ex_vector, /* Hold debugger_active */ procid = raw_smp_processor_id(); - while (cmpxchg(&atomic_read(&debugger_active), 0, (procid + 1)) != 0) { + while (1) { int i = 25; /* an arbitrary number */ + if (atomic_read(&kgdb_sync) < 0 && + atomic_inc_and_test(&kgdb_sync)) { + atomic_set(&debugger_active, procid + 1); + break; + } while (--i) cpu_relax(); @@ -991,6 +1003,7 @@ int kgdb_handle_exception(int ex_vector, if (atomic_read(&cpu_doing_single_step) != -1 && atomic_read(&cpu_doing_single_step) != procid) { atomic_set(&debugger_active, 0); + atomic_set(&kgdb_sync, -1); clocksource_touch_watchdog(); kgdb_softlock_skip[procid] = 1; local_irq_restore(flags); @@ -1557,6 +1570,7 @@ int kgdb_handle_exception(int ex_vector, kgdb_restore: /* Free debugger_active */ atomic_set(&debugger_active, 0); + atomic_set(&kgdb_sync, -1); clocksource_touch_watchdog(); kgdb_softlock_skip[processor] = 1; local_irq_restore(flags);