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