summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_umtx.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2013-03-21 19:58:25 +0000
committerattilio <attilio@FreeBSD.org>2013-03-21 19:58:25 +0000
commit83c8ef372d1d4027b084f1a71f06d2ad2ec1401c (patch)
treeaa51b7c3f2a12fd8f27845fcf927a1320bd05fc3 /sys/kern/kern_umtx.c
parent22bd645df5a40221f99bed0e0e207bd817e30aa9 (diff)
downloadFreeBSD-src-83c8ef372d1d4027b084f1a71f06d2ad2ec1401c.zip
FreeBSD-src-83c8ef372d1d4027b084f1a71f06d2ad2ec1401c.tar.gz
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
Diffstat (limited to 'sys/kern/kern_umtx.c')
-rw-r--r--sys/kern/kern_umtx.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index f50a6f9..6026b80 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -542,19 +542,19 @@ umtxq_insert_queue(struct umtx_q *uq, int q)
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, int q)
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);
OpenPOWER on IntegriCloud