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
This commit is contained in:
parent
b7e2b86cec
commit
d52d7aa871
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248591
@ -542,19 +542,19 @@ umtxq_insert_queue(struct umtx_q *uq, int q)
|
|||||||
uh = uq->uq_spare_queue;
|
uh = uq->uq_spare_queue;
|
||||||
uh->key = uq->uq_key;
|
uh->key = uq->uq_key;
|
||||||
LIST_INSERT_HEAD(&uc->uc_queue[q], uh, link);
|
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;
|
uq->uq_spare_queue = NULL;
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&uh->head, uq, uq_link);
|
TAILQ_INSERT_TAIL(&uh->head, uq, uq_link);
|
||||||
uh->length++;
|
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_flags |= UQF_UMTXQ;
|
||||||
uq->uq_cur_queue = uh;
|
uq->uq_cur_queue = uh;
|
||||||
return;
|
return;
|
||||||
@ -572,13 +572,13 @@ umtxq_remove_queue(struct umtx_q *uq, int q)
|
|||||||
uh = uq->uq_cur_queue;
|
uh = uq->uq_cur_queue;
|
||||||
TAILQ_REMOVE(&uh->head, uq, uq_link);
|
TAILQ_REMOVE(&uh->head, uq, uq_link);
|
||||||
uh->length--;
|
uh->length--;
|
||||||
#ifdef UMTX_PROFILING
|
|
||||||
uc->length--;
|
|
||||||
#endif
|
|
||||||
uq->uq_flags &= ~UQF_UMTXQ;
|
uq->uq_flags &= ~UQF_UMTXQ;
|
||||||
if (TAILQ_EMPTY(&uh->head)) {
|
if (TAILQ_EMPTY(&uh->head)) {
|
||||||
KASSERT(uh->length == 0,
|
KASSERT(uh->length == 0,
|
||||||
("inconsistent umtxq_queue length"));
|
("inconsistent umtxq_queue length"));
|
||||||
|
#ifdef UMTX_PROFILING
|
||||||
|
uc->length--;
|
||||||
|
#endif
|
||||||
LIST_REMOVE(uh, link);
|
LIST_REMOVE(uh, link);
|
||||||
} else {
|
} else {
|
||||||
uh = LIST_FIRST(&uc->uc_spare_queue);
|
uh = LIST_FIRST(&uc->uc_spare_queue);
|
||||||
|
Loading…
Reference in New Issue
Block a user