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


Reply via email to