Add a DEBUG_TOKENS option which causes token operations to be logged to
authorMatthew Dillon <dillon@dragonflybsd.org>
Mon, 20 Jun 2005 07:58:39 +0000 (07:58 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Mon, 20 Jun 2005 07:58:39 +0000 (07:58 +0000)
a static array, suitable for post-morten investigation.

sys/conf/options
sys/kern/lwkt_token.c

index 9ced4d7..c173216 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/options,v 1.191.2.53 2003/06/04 17:56:58 sam Exp $
-# $DragonFly: src/sys/conf/options,v 1.31 2005/03/01 00:43:02 corecode Exp $
+# $DragonFly: src/sys/conf/options,v 1.32 2005/06/20 07:58:37 dillon Exp $
 #
 #        On the handling of kernel options
 #
@@ -406,6 +406,7 @@ BLKDEV_IOSIZE               opt_global.h
 DEBUG                  opt_global.h
 DEBUG_LOCKS            opt_global.h
 DEBUG_VFS_LOCKS                opt_global.h
+DEBUG_TOKENS           opt_global.h
 DIAGNOSTIC             opt_global.h
 INVARIANT_SUPPORT      opt_global.h
 INVARIANTS             opt_global.h
index 55f8578..c38e816 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/lwkt_token.c,v 1.17 2005/06/20 07:40:30 dillon Exp $
+ * $DragonFly: src/sys/kern/lwkt_token.c,v 1.18 2005/06/20 07:58:39 dillon Exp $
  */
 
 #ifdef _KERNEL
@@ -102,6 +102,52 @@ static void lwkt_reqtoken_remote(void *data);
 
 static lwkt_token      pool_tokens[LWKT_NUM_POOL_TOKENS];
 
+/*
+ * Token debugging code, log token operations and who called them.
+ */
+#ifdef DEBUG_TOKENS
+
+static struct toklog {
+    enum tokenum { TOKTRY, TOKGET, TOKREL1, TOKREL2, TOKREMOTE,
+                  TOKREQREMOTE, TOKREQFAIL, TOKDRAIN } type;
+    int toremote;
+    lwkt_tokref_t ref;
+    lwkt_token_t tok;
+    thread_t td;
+    void *caller;
+} toklog[SMP_MAXCPU][2048];
+
+static int tokindex[SMP_MAXCPU];
+
+static void
+logtoken(lwkt_tokref_t ref, void *stackptr, enum tokenum type)
+{
+    struct toklog *log;
+    globaldata_t gd;
+
+    if (panicstr == NULL) {
+       gd = mycpu;
+       crit_enter();
+       log = &toklog[gd->gd_cpuid][tokindex[gd->gd_cpuid]];
+       log->type = type;
+       log->ref = ref;
+       log->tok = ref->tr_tok;
+       if (stackptr)
+           log->caller = ((void **)stackptr)[-1];
+       else
+           log->caller = NULL;
+       log->td = gd->gd_curthread;
+       tokindex[gd->gd_cpuid] = (tokindex[gd->gd_cpuid] + 1) & 2047;
+       crit_exit();
+    }
+}
+
+#else
+
+#define logtoken(ref, stackptr, type)
+
+#endif
+
 #ifdef _KERNEL
 
 #ifdef INVARIANTS
@@ -152,9 +198,14 @@ lwkt_chktokens(thread_t td)
                refs->tr_magic = LWKT_TOKREF_MAGIC2;    /* MP synched slowreq*/
                refs->tr_reqgd = gd;
                tok->t_reqcpu = gd;     /* MP unsynchronized 'fast' req */
+
+               logtoken(refs, &td, TOKREQREMOTE);
+
                if (lwkt_send_ipiq_nowait(dgd, lwkt_reqtoken_remote, refs)) {
                    /* failed */
                    refs->tr_magic = LWKT_TOKREF_MAGIC1;
+
+                   logtoken(refs, &td, TOKREQFAIL);
                    break;
                }
            } else if (magic != LWKT_TOKREF_MAGIC2) {
@@ -380,12 +431,14 @@ void
 lwkt_gettoken(lwkt_tokref_t ref, lwkt_token_t tok)
 {
     lwkt_tokref_init(ref, tok);
+    logtoken(ref, &ref, TOKGET);
     _lwkt_gettokref(ref);
 }
 
 void
 lwkt_gettokref(lwkt_tokref_t ref)
 {
+    logtoken(ref, &ref, TOKGET);
     _lwkt_gettokref(ref);
 }
 
@@ -393,12 +446,14 @@ int
 lwkt_trytoken(lwkt_tokref_t ref, lwkt_token_t tok)
 {
     lwkt_tokref_init(ref, tok);
+    logtoken(ref, &ref, TOKTRY);
     return(_lwkt_trytokref(ref));
 }
 
 int
 lwkt_trytokref(lwkt_tokref_t ref)
 {
+    logtoken(ref, &ref, TOKTRY);
     return(_lwkt_trytokref(ref));
 }
 
@@ -416,6 +471,7 @@ lwkt_reltoken(lwkt_tokref *_ref)
     thread_t td;
     int giveaway;
 
+    logtoken(_ref, &_ref, TOKREL1);
     /*
      * Guard check and stack check (if in the same stack page).  We must
      * also wait for any action pending on remote cpus which we do by
@@ -527,6 +583,7 @@ lwkt_reqtoken_remote(void *data)
     globaldata_t gd = mycpu;
     lwkt_token_t tok = ref->tr_tok;
 
+    logtoken(ref, &data, TOKREMOTE);
     /*
      * We do not have to queue the token if we can give it away
      * immediately.  Otherwise we queue it to our globaldata structure.