[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 10/79] qsp: use atomic64 accessors
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 10/79] qsp: use atomic64 accessors |
Date: |
Sun, 30 Sep 2018 10:12:08 +0200 |
From: "Emilio G. Cota" <address@hidden>
With the seqlock, we either have to use atomics to remain
within defined behaviour (and note that 64-bit atomics aren't
always guaranteed to compile, irrespective of __nocheck), or
drop the atomics and be in undefined behaviour territory.
Fix it by dropping the seqlock and using atomic64 accessors.
This will limit scalability when !CONFIG_ATOMIC64, but those
machines (1) don't have many users and (2) are unlikely to
have many cores.
- With CONFIG_ATOMIC64:
$ tests/atomic_add-bench -n 1 -m -p
Throughput: 13.00 Mops/s
- Forcing !CONFIG_ATOMIC64:
$ tests/atomic_add-bench -n 1 -m -p
Throughput: 10.89 Mops/s
Signed-off-by: Emilio G. Cota <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
util/qsp.c | 49 ++++++++-----------------------------------------
1 file changed, 8 insertions(+), 41 deletions(-)
diff --git a/util/qsp.c b/util/qsp.c
index b0c2575..c16af03 100644
--- a/util/qsp.c
+++ b/util/qsp.c
@@ -84,13 +84,6 @@ struct QSPEntry {
uint64_t n_acqs;
uint64_t ns;
unsigned int n_objs; /* count of coalesced objs; only used for reporting */
-#ifndef CONFIG_ATOMIC64
- /*
- * If we cannot update the counts atomically, then use a seqlock.
- * We don't need an associated lock because the updates are thread-local.
- */
- QemuSeqLock sequence;
-#endif
};
typedef struct QSPEntry QSPEntry;
@@ -345,46 +338,15 @@ static QSPEntry *qsp_entry_get(const void *obj, const
char *file, int line,
}
/*
- * @from is in the global hash table; read it atomically if the host
- * supports it, otherwise use the seqlock.
- */
-static void qsp_entry_aggregate(QSPEntry *to, const QSPEntry *from)
-{
-#ifdef CONFIG_ATOMIC64
- to->ns += atomic_read__nocheck(&from->ns);
- to->n_acqs += atomic_read__nocheck(&from->n_acqs);
-#else
- unsigned int version;
- uint64_t ns, n_acqs;
-
- do {
- version = seqlock_read_begin(&from->sequence);
- ns = atomic_read__nocheck(&from->ns);
- n_acqs = atomic_read__nocheck(&from->n_acqs);
- } while (seqlock_read_retry(&from->sequence, version));
-
- to->ns += ns;
- to->n_acqs += n_acqs;
-#endif
-}
-
-/*
* @e is in the global hash table; it is only written to by the current thread,
* so we write to it atomically (as in "write once") to prevent torn reads.
- * If the host doesn't support u64 atomics, use the seqlock.
*/
static inline void do_qsp_entry_record(QSPEntry *e, int64_t delta, bool acq)
{
-#ifndef CONFIG_ATOMIC64
- seqlock_write_begin(&e->sequence);
-#endif
- atomic_set__nocheck(&e->ns, e->ns + delta);
+ atomic_set_u64(&e->ns, e->ns + delta);
if (acq) {
- atomic_set__nocheck(&e->n_acqs, e->n_acqs + 1);
+ atomic_set_u64(&e->n_acqs, e->n_acqs + 1);
}
-#ifndef CONFIG_ATOMIC64
- seqlock_write_end(&e->sequence);
-#endif
}
static inline void qsp_entry_record(QSPEntry *e, int64_t delta)
@@ -550,7 +512,12 @@ static void qsp_aggregate(struct qht *global_ht, void *p,
uint32_t h, void *up)
hash = qsp_entry_no_thread_hash(e);
agg = qsp_entry_find(ht, e, hash);
- qsp_entry_aggregate(agg, e);
+ /*
+ * The entry is in the global hash table; read from it atomically (as in
+ * "read once").
+ */
+ agg->ns += atomic_read_u64(&e->ns);
+ agg->n_acqs += atomic_read_u64(&e->n_acqs);
}
static void qsp_iter_diff(struct qht *orig, void *p, uint32_t hash, void *htp)
--
1.8.3.1
- [Qemu-devel] [PULL 07/79] cacheinfo: add i/d cache_linesize_log, (continued)
- [Qemu-devel] [PULL 07/79] cacheinfo: add i/d cache_linesize_log, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 05/79] atomic: fix comment s/x64_64/x86_64/, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 01/79] virtio: Return true from virtio_queue_empty if broken, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 09/79] tests: add atomic64-bench, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 16/79] hostmem-memfd: add checks before adding hostmem-memfd & properties, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 13/79] cpus: access .qemu_icount with atomic64, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 12/79] cpus: take seqlock across qemu_icount updates, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 14/79] cpus: access .qemu_icount_bias with atomic64, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 17/79] kvm: x86: Fix kvm_arch_fixup_msi_route for remap-less case, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 22/79] serial: fix DLL writes, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 10/79] qsp: use atomic64 accessors,
Paolo Bonzini <=
- [Qemu-devel] [PULL 15/79] dump: fix Windows dump memory run mapping, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 11/79] test-rcu-list: access n_reclaims and n_nodes_removed with atomic64, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 18/79] configure: preserve various environment variables in config.status, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 19/79] hw/char/sh_serial: Add timeout handling to unbreak serial input, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 21/79] util: use fcntl() for qemu_write_pidfile() locking, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 20/79] util: add qemu_write_pidfile(), Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 23/79] Delete PID file on exit, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 24/79] change get_image_size return type to int64_t, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 25/79] target/i386: move cpu_cc_srcT to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 28/79] target/i386: move cpu_T1 to DisasContext, Paolo Bonzini, 2018/09/30