svn commit: r248591 - head/sys/kern

Attilio Rao attilio at FreeBSD.org
Thu Mar 21 19:58:26 UTC 2013


Author: attilio
Date: Thu Mar 21 19:58:25 2013
New Revision: 248591
URL: http://svnweb.freebsd.org/changeset/base/248591

Log:
  Fix a bug in UMTX_PROFILING:
  UMTX_PROFILING should really analyze the distribution of locks as they
  index entries in the umtxq_chains hash-table.
  However, the current implementation does add/dec the length counters
  for *every* thread insert/removal, measuring at all really userland
  contention and not the hash distribution.
  
  Fix this by correctly add/dec the length counters in the points where
  it is really needed.
  
  Please note that this bug brought us questioning in the past the quality
  of the umtx hash table distribution.
  To date with all the benchmarks I could try I was not able to reproduce
  any issue about the hash distribution on umtx.
  
  Sponsored by:	EMC / Isilon storage division
  Reviewed by:	jeff, davide
  MFC after:	2 weeks

Modified:
  head/sys/kern/kern_umtx.c

Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c	Thu Mar 21 18:59:02 2013	(r248590)
+++ head/sys/kern/kern_umtx.c	Thu Mar 21 19:58:25 2013	(r248591)
@@ -542,19 +542,19 @@ umtxq_insert_queue(struct umtx_q *uq, in
 		uh = uq->uq_spare_queue;
 		uh->key = uq->uq_key;
 		LIST_INSERT_HEAD(&uc->uc_queue[q], uh, link);
+#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_spare_queue = NULL;
 
 	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;
@@ -572,13 +572,13 @@ 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,
 			    ("inconsistent umtxq_queue length"));
+#ifdef UMTX_PROFILING
+			uc->length--;
+#endif
 			LIST_REMOVE(uh, link);
 		} else {
 			uh = LIST_FIRST(&uc->uc_spare_queue);


More information about the svn-src-all mailing list