[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 09/15] util/qht: atomically set b->hashes
From: |
Alex Bennée |
Subject: |
[Qemu-devel] [PATCH v3 09/15] util/qht: atomically set b->hashes |
Date: |
Fri, 30 Sep 2016 22:31:00 +0100 |
ThreadSanitizer detects a possible race between reading/writing the
hashes. The ordering semantics are already documented for QHT however
for true C11 compliance we should use relaxed atomic primitives for
accesses that are done across threads. On x86 this slightly changes to
the code to not do a load/compare in a single instruction leading to a
slight performance degradation.
Running 'taskset -c 0 tests/qht-bench -n 1 -d 10' (i.e. all lookups) 10
times, we get:
before the patch:
$ ./mean.pl 34.04 34.24 34.38 34.25 34.18 34.51 34.46 34.44 34.29 34.08
34.287 +- 0.160072900059109
after:
$ ./mean.pl 33.94 34.00 33.52 33.46 33.55 33.71 34.27 34.06 34.28 34.58
33.937 +- 0.374731014640279
Signed-off-by: Alex Bennée <address@hidden>
Reviewed-by: Emilio G. Cota <address@hidden>
---
util/qht.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/util/qht.c b/util/qht.c
index 16a8d79..571639d 100644
--- a/util/qht.c
+++ b/util/qht.c
@@ -379,7 +379,7 @@ static void qht_bucket_reset__locked(struct qht_bucket
*head)
if (b->pointers[i] == NULL) {
goto done;
}
- b->hashes[i] = 0;
+ atomic_set(&b->hashes[i], 0);
atomic_set(&b->pointers[i], NULL);
}
b = b->next;
@@ -444,7 +444,7 @@ void *qht_do_lookup(struct qht_bucket *head,
qht_lookup_func_t func,
do {
for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
- if (b->hashes[i] == hash) {
+ if (atomic_read(&b->hashes[i]) == hash) {
/* The pointer is dereferenced before seqlock_read_retry,
* so (unlike qht_insert__locked) we need to use
* atomic_rcu_read here.
@@ -538,8 +538,8 @@ static bool qht_insert__locked(struct qht *ht, struct
qht_map *map,
if (new) {
atomic_rcu_set(&prev->next, b);
}
- b->hashes[i] = hash;
/* smp_wmb() implicit in seqlock_write_begin. */
+ atomic_set(&b->hashes[i], hash);
atomic_set(&b->pointers[i], p);
seqlock_write_end(&head->sequence);
return true;
@@ -607,10 +607,10 @@ qht_entry_move(struct qht_bucket *to, int i, struct
qht_bucket *from, int j)
qht_debug_assert(to->pointers[i]);
qht_debug_assert(from->pointers[j]);
- to->hashes[i] = from->hashes[j];
+ atomic_set(&to->hashes[i], from->hashes[j]);
atomic_set(&to->pointers[i], from->pointers[j]);
- from->hashes[j] = 0;
+ atomic_set(&from->hashes[j], 0);
atomic_set(&from->pointers[j], NULL);
}
--
2.9.3
- [Qemu-devel] [PATCH v3 10/15] linux-user/syscall: extend lock around cpu-list, (continued)
- [Qemu-devel] [PATCH v3 10/15] linux-user/syscall: extend lock around cpu-list, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 05/15] seqlock: use atomic writes for the sequence, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 08/15] cpu: atomically modify cpu->exit_request, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 07/15] qom/cpu: atomically clear the tb_jmp_cache, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 11/15] qga/command: use QEMU atomic primitives, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 12/15] .travis.yml: add gcc sanitizer build, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 13/15] tcg: ensure cpu_tb_exec/tb_gen_code use atomic_read/write, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 15/15] translate-all: mark updates to PageDesc as atomic, Alex Bennée, 2016/09/30
- [Qemu-devel] [PATCH v3 09/15] util/qht: atomically set b->hashes,
Alex Bennée <=
- [Qemu-devel] [PATCH v3 14/15] tcg: update remaining TranslationBuffer fields atomically, Alex Bennée, 2016/09/30
- Re: [Qemu-devel] [PATCH v3 00/15] A number of fixes for ThreadSanitizer, no-reply, 2016/09/30
- Re: [Qemu-devel] [PATCH v3 00/15] A number of fixes for ThreadSanitizer, no-reply, 2016/09/30