Author: davide
Date: Fri Mar 16 20:32:11 2012
New Revision: 233045
URL: http://svn.freebsd.org/changeset/base/233045

Log:
  Add rudimentary profiling of the hash table used in the in the umtx code to
  hold active lock queues.
  
  Reviewed by:  attilio
  Approved by:  davidxu, gnn (mentor)
  MFC after:    3 weeks

Modified:
  head/sys/conf/NOTES
  head/sys/conf/options
  head/sys/kern/kern_umtx.c

Modified: head/sys/conf/NOTES
==============================================================================
--- head/sys/conf/NOTES Fri Mar 16 20:24:30 2012        (r233044)
+++ head/sys/conf/NOTES Fri Mar 16 20:32:11 2012        (r233045)
@@ -274,6 +274,8 @@ options     SX_NOINLINE
 #        frequency.
 # TURNSTILE_PROFILING enables rudimentary profiling of the hash table
 #        used to hold active lock queues.
+# UMTX_PROFILING enables rudimentary profiling of the hash table used 
+         to hold active lock queues.
 # WITNESS enables the witness code which detects deadlocks and cycles
 #         during locking operations.
 # WITNESS_KDB causes the witness code to drop into the kernel debugger if
@@ -297,8 +299,8 @@ options     MPROF_HASH_SIZE="1543"
 # Profiling for internal hash tables.
 options        SLEEPQUEUE_PROFILING
 options        TURNSTILE_PROFILING
+options                UMTX_PROFILING
 
-
 #####################################################################
 # COMPATIBILITY OPTIONS
 

Modified: head/sys/conf/options
==============================================================================
--- head/sys/conf/options       Fri Mar 16 20:24:30 2012        (r233044)
+++ head/sys/conf/options       Fri Mar 16 20:32:11 2012        (r233045)
@@ -186,6 +186,7 @@ SYSVSEM             opt_sysvipc.h
 SYSVSHM                opt_sysvipc.h
 SW_WATCHDOG    opt_watchdog.h
 TURNSTILE_PROFILING
+UMTX_PROFILING
 VFS_AIO
 VFS_ALLOW_NONMPSAFE
 VERBOSE_SYSINIT        opt_global.h

Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c   Fri Mar 16 20:24:30 2012        (r233044)
+++ head/sys/kern/kern_umtx.c   Fri Mar 16 20:32:11 2012        (r233045)
@@ -29,6 +29,8 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_compat.h"
+#include "opt_umtx_profiling.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/limits.h>
@@ -154,6 +156,10 @@ struct umtxq_chain {
        /* All PI in the list */
        TAILQ_HEAD(,umtx_pi)    uc_pi_list;
 
+#ifdef UMTX_PROFILING
+       int                     length;
+       int                     max_length;
+#endif
 };
 
 #define        UMTXQ_LOCKED_ASSERT(uc)         mtx_assert(&(uc)->uc_lock, 
MA_OWNED)
@@ -190,6 +196,12 @@ static SYSCTL_NODE(_debug, OID_AUTO, umt
 SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_pi_allocated, CTLFLAG_RD,
     &umtx_pi_allocated, 0, "Allocated umtx_pi");
 
+#ifdef UMTX_PROFILING
+static long max_length;
+SYSCTL_LONG(_debug_umtx, OID_AUTO, max_length, CTLFLAG_RD, &max_length, 0, 
"max_length");
+static SYSCTL_NODE(_debug_umtx, OID_AUTO, chains, CTLFLAG_RD, 0, "umtx chain 
stats");
+#endif
+
 static void umtxq_sysinit(void *);
 static void umtxq_hash(struct umtx_key *key);
 static struct umtxq_chain *umtxq_getchain(struct umtx_key *key);
@@ -215,6 +227,27 @@ SYSINIT(umtx, SI_SUB_EVENTHANDLER+1, SI_
 
 static struct mtx umtx_lock;
 
+#ifdef UMTX_PROFILING
+static void
+umtx_init_profiling(void) 
+{
+       struct sysctl_oid *chain_oid;
+       char chain_name[10];
+       int i;
+
+       for (i = 0; i < UMTX_CHAINS; ++i) {
+               snprintf(chain_name, sizeof(chain_name), "%d", i);
+               chain_oid = SYSCTL_ADD_NODE(NULL, 
+                   SYSCTL_STATIC_CHILDREN(_debug_umtx_chains), OID_AUTO, 
+                   chain_name, CTLFLAG_RD, NULL, "umtx hash stats");
+               SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(chain_oid), OID_AUTO,
+                   "max_length0", CTLFLAG_RD, &umtxq_chains[0][i].max_length, 
0, NULL);
+               SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(chain_oid), OID_AUTO,
+                   "max_length1", CTLFLAG_RD, &umtxq_chains[1][i].max_length, 
0, NULL);
+       }
+}
+#endif
+
 static void
 umtxq_sysinit(void *arg __unused)
 {
@@ -232,8 +265,15 @@ umtxq_sysinit(void *arg __unused)
                        TAILQ_INIT(&umtxq_chains[i][j].uc_pi_list);
                        umtxq_chains[i][j].uc_busy = 0;
                        umtxq_chains[i][j].uc_waiters = 0;
+                       #ifdef UMTX_PROFILING
+                       umtxq_chains[i][j].length = 0;
+                       umtxq_chains[i][j].max_length = 0;      
+                       #endif
                }
        }
+       #ifdef UMTX_PROFILING
+       umtx_init_profiling();
+       #endif
        mtx_init(&umtx_lock, "umtx lock", NULL, MTX_SPIN);
        EVENTHANDLER_REGISTER(process_exec, umtx_exec_hook, NULL,
            EVENTHANDLER_PRI_ANY);
@@ -384,6 +424,14 @@ umtxq_insert_queue(struct umtx_q *uq, in
 
        TAILQ_INSERT_TAIL(&uh->head, uq, uq_link);
        uh->length++;
+       #ifdef UMTX_PROFILING
+       uc->length++;
+       if (uc->length > uc->max_length) {
+               uc->max_length = uc->length;
+               if (uc->max_length > max_length)
+                       max_length = uc->max_length;    
+       }
+       #endif
        uq->uq_flags |= UQF_UMTXQ;
        uq->uq_cur_queue = uh;
        return;
@@ -401,6 +449,9 @@ umtxq_remove_queue(struct umtx_q *uq, in
                uh = uq->uq_cur_queue;
                TAILQ_REMOVE(&uh->head, uq, uq_link);
                uh->length--;
+               #ifdef UMTX_PROFILING
+               uc->length--;
+               #endif
                uq->uq_flags &= ~UQF_UMTXQ;
                if (TAILQ_EMPTY(&uh->head)) {
                        KASSERT(uh->length == 0,
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to