[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 12/22] translate-all: make l1_map lockless
From: |
Emilio G. Cota |
Subject: |
[Qemu-devel] [PATCH 12/22] translate-all: make l1_map lockless |
Date: |
Mon, 7 Aug 2017 19:52:28 -0400 |
Groundwork for supporting parallel TCG generation.
We never remove entries from the radix tree, so we can use cmpxchg
to implement lockless insertions.
Signed-off-by: Emilio G. Cota <address@hidden>
---
docs/devel/multi-thread-tcg.txt | 4 ++--
accel/tcg/translate-all.c | 24 ++++++++++++++----------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/docs/devel/multi-thread-tcg.txt b/docs/devel/multi-thread-tcg.txt
index a99b456..faf8918 100644
--- a/docs/devel/multi-thread-tcg.txt
+++ b/docs/devel/multi-thread-tcg.txt
@@ -134,8 +134,8 @@ tb_set_jmp_target() code. Modification to the linked lists
that allow
searching for linked pages are done under the protect of the
tb_lock().
-The global page table is protected by the tb_lock() in system-mode and
-mmap_lock() in linux-user mode.
+The global page table is a lockless radix tree; cmpxchg is used
+to atomically insert new elements.
The lookup caches are updated atomically and the lookup hash uses QHT
which is designed for concurrent safe lookup.
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 0e3d223..12e1252 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -482,20 +482,12 @@ static void page_init(void)
#endif
}
-/* If alloc=1:
- * Called with tb_lock held for system emulation.
- * Called with mmap_lock held for user-mode emulation.
- */
static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
{
PageDesc *pd;
void **lp;
int i;
- if (alloc) {
- assert_memory_lock();
- }
-
/* Level 1. Always allocated. */
lp = l1_map + ((index >> v_l1_shift) & (v_l1_size - 1));
@@ -504,11 +496,17 @@ static PageDesc *page_find_alloc(tb_page_addr_t index,
int alloc)
void **p = atomic_rcu_read(lp);
if (p == NULL) {
+ void *existing;
+
if (!alloc) {
return NULL;
}
p = g_new0(void *, V_L2_SIZE);
- atomic_rcu_set(lp, p);
+ existing = atomic_cmpxchg(lp, NULL, p);
+ if (unlikely(existing)) {
+ g_free(p);
+ p = existing;
+ }
}
lp = p + ((index >> (i * V_L2_BITS)) & (V_L2_SIZE - 1));
@@ -516,11 +514,17 @@ static PageDesc *page_find_alloc(tb_page_addr_t index,
int alloc)
pd = atomic_rcu_read(lp);
if (pd == NULL) {
+ void *existing;
+
if (!alloc) {
return NULL;
}
pd = g_new0(PageDesc, V_L2_SIZE);
- atomic_rcu_set(lp, pd);
+ existing = atomic_cmpxchg(lp, NULL, pd);
+ if (unlikely(existing)) {
+ g_free(pd);
+ pd = existing;
+ }
}
return pd + (index & (V_L2_SIZE - 1));
--
2.7.4
- [Qemu-devel] [PATCH 00/22] tcg: tb_lock removal, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 02/22] linux-user: fix 'finshed' typo in comment, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 03/22] translate-all: fix 'consisits' typo in comment, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 09/22] translate-all: introduce iterator macros for tagged TB lists, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 01/22] disas/arm: fix 'instuction' typo in comment, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 04/22] qht: fix kernel-doc markup in qht.h, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 11/22] translate-all: exit from tb_phys_invalidate if qht_remove fails, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 08/22] tcg: move tb_ctx.tb_phys_invalidate_count to tcg_ctx, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 13/22] translate-all: remove hole in PageDesc, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 12/22] translate-all: make l1_map lockless,
Emilio G. Cota <=
- [Qemu-devel] [PATCH 05/22] qht: require a default comparison function, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 06/22] qht: return existing entry when qht_insert fails, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 15/22] translate-all: move tb_invalidate_phys_page_range up in the file, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 10/22] translate-all: iterate over TBs in a page with page_for_each_tb, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 17/22] translate-all: discard TB when tb_link_page returns an existing matching TB, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 16/22] translate-all: use per-page locking in !user-mode, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 07/22] tcg: track TBs with per-region BST's, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 14/22] translate-all: work page-by-page in tb_invalidate_phys_range_1, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 18/22] translate-all: protect TB jumps with a per-destination-TB lock, Emilio G. Cota, 2017/08/07
- [Qemu-devel] [PATCH 20/22] exec: remove tb_lock from notdirty_mem_write, Emilio G. Cota, 2017/08/07