On Tue, 10 Jun 2003 11:50:22 -0400,
"Sanders, Richard" <[EMAIL PROTECTED]> wrote:
>Ok, my first patch was pretty badly broken... try two.
>
>Between the smp race on this test and set flag:
>
>if (!KDB_STATE(PRINTF_LOCK)) {
> KDB_STATE_SET(PRINTF_LOCK);
> spin_lock(&kdb_printf_lock);
>}
>
>... and the fact that in the inner calls of a recursive kdb_printf this test
>is trues:
>
>if (KDB_STATE(PRINTF_LOCK)) {
> spin_unlock(&kdb_printf_lock);
> KDB_STATE_CLEAR(PRINTF_LOCK);
>}
>
>... the possibility exists to get the PRINTF_LOCK state and the spin_lock
>state out of sync, eventually leading to a deadlock.
>
>What I have done is intoduce a recursion count to ensure that only the outer
>call is interacting with the smp serialization, with data locking to prevent
>racing. This replaces the functionality of the KDB_STATE_PRINTF_LOCK.
This should have the same effect and is much simpler. It will only
unlock and clear the state in the same logic flow that got the lock.
--- linux/kdb/kdb_io.c Wed Jun 11 12:33:11 2003
+++ linux/kdb/kdb_io.c Wed Jun 11 12:32:53 2003
@@ -486,6 +486,7 @@
int linecount;
int logging, saved_loglevel = 0;
int do_longjmp = 0;
+ int got_printf_lock = 0;
struct console *c = console_drivers;
static spinlock_t kdb_printf_lock = SPIN_LOCK_UNLOCKED;
@@ -496,6 +497,7 @@
if (!KDB_STATE(PRINTF_LOCK)) {
KDB_STATE_SET(PRINTF_LOCK);
spin_lock(&kdb_printf_lock);
+ got_printf_lock = 1;
}
diag = kdbgetintenv("LINES", &linecount);
@@ -591,9 +593,10 @@
if (logging) {
console_loglevel = saved_loglevel;
}
- if (KDB_STATE(PRINTF_LOCK)) {
+ if (KDB_STATE(PRINTF_LOCK) && got_printf_lock) {
spin_unlock(&kdb_printf_lock);
KDB_STATE_CLEAR(PRINTF_LOCK);
+ got_printf_lock = 0;
}
if (do_longjmp)
#ifdef KDB_HAVE_LONGJMP