* [Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock
@ 2019-09-11 19:06 Dr. David Alan Gilbert (git)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant Dr. David Alan Gilbert (git)
` (4 more replies)
0 siblings, 5 replies; 17+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-11 19:06 UTC (permalink / raw)
To: qemu-devel, pbonzini, ehabkost, berrange, quintela
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
This patch uses glib's g_auto mechanism to automatically free
rcu_read_lock's at the end of the block. Given that humans
have a habit of forgetting an error path somewhere it's
best to leave it to the compiler.
(Note I've found the actual cause of my deadlock actually
isn't a misisng unlock; it's a lock ordering thing)
v2
Rework auto mechanism based on Dan and Eduardo's comments
Add some more uses in memory/exec
Add a missing unlock in a function I've not used the macro in
Dr. David Alan Gilbert (5):
rcu: Add automatically released rcu_read_lock variant
migration: Use automatic rcu_read unlock in ram.c
migration: Use automatic rcu_read unlock in rdma.c
rcu: Use automatic rc_read unlock in core memory/exec code
migration: Missing rcu_read_unlock
exec.c | 46 ++++++++++-----------------------
include/exec/ram_addr.h | 8 ++----
include/qemu/rcu.h | 18 +++++++++++++
memory.c | 15 ++++-------
migration/ram.c | 26 ++++++++-----------
migration/rdma.c | 57 ++++++++---------------------------------
6 files changed, 60 insertions(+), 110 deletions(-)
--
2.21.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant
2019-09-11 19:06 [Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock Dr. David Alan Gilbert (git)
@ 2019-09-11 19:06 ` Dr. David Alan Gilbert (git)
2019-09-12 9:35 ` Daniel P. Berrangé
2019-09-12 12:30 ` Paolo Bonzini
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 2/5] migration: Use automatic rcu_read unlock in ram.c Dr. David Alan Gilbert (git)
` (3 subsequent siblings)
4 siblings, 2 replies; 17+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-11 19:06 UTC (permalink / raw)
To: qemu-devel, pbonzini, ehabkost, berrange, quintela
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
RCU_READ_LOCK_AUTO takes the rcu_read_lock and then uses glib's
g_auto infrastructure (and thus whatever the compiler's hooks are) to
release it on all exits of the block.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
include/qemu/rcu.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index 22876d1428..8768a7b60a 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -154,6 +154,24 @@ extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func);
}), \
(RCUCBFunc *)g_free);
+typedef void RCUReadAuto;
+static inline RCUReadAuto *rcu_read_auto_lock(void)
+{
+ rcu_read_lock();
+ /* Anything non-NULL causes the cleanup function to be called */
+ return (void *)0x1;
+}
+
+static inline void rcu_read_auto_unlock(RCUReadAuto *r)
+{
+ rcu_read_unlock();
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(RCUReadAuto, rcu_read_auto_unlock)
+
+#define RCU_READ_LOCK_AUTO \
+ g_autoptr(RCUReadAuto) _rcu_read_auto = rcu_read_auto_lock()
+
#ifdef __cplusplus
}
#endif
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v2 2/5] migration: Use automatic rcu_read unlock in ram.c
2019-09-11 19:06 [Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock Dr. David Alan Gilbert (git)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant Dr. David Alan Gilbert (git)
@ 2019-09-11 19:06 ` Dr. David Alan Gilbert (git)
2019-09-12 9:37 ` Daniel P. Berrangé
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 3/5] migration: Use automatic rcu_read unlock in rdma.c Dr. David Alan Gilbert (git)
` (2 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-11 19:06 UTC (permalink / raw)
To: qemu-devel, pbonzini, ehabkost, berrange, quintela
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Use the automatic read unlocker in migration/ram.c;
only for the cases where the unlock is at the end of the function.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/ram.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/migration/ram.c b/migration/ram.c
index b2bd618a89..1bb82acfe0 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -181,14 +181,14 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque)
RAMBlock *block;
int ret = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
+
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
ret = func(block, opaque);
if (ret) {
break;
}
}
- rcu_read_unlock();
return ret;
}
@@ -2398,13 +2398,12 @@ static void migration_page_queue_free(RAMState *rs)
/* This queue generally should be empty - but in the case of a failed
* migration might have some droppings in.
*/
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
QSIMPLEQ_FOREACH_SAFE(mspr, &rs->src_page_requests, next_req, next_mspr) {
memory_region_unref(mspr->rb->mr);
QSIMPLEQ_REMOVE_HEAD(&rs->src_page_requests, next_req);
g_free(mspr);
}
- rcu_read_unlock();
}
/**
@@ -2425,7 +2424,8 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len)
RAMState *rs = ram_state;
ram_counters.postcopy_requests++;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
+
if (!rbname) {
/* Reuse last RAMBlock */
ramblock = rs->last_req_rb;
@@ -2467,12 +2467,10 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len)
QSIMPLEQ_INSERT_TAIL(&rs->src_page_requests, new_entry, next_req);
migration_make_urgent_request();
qemu_mutex_unlock(&rs->src_page_req_mutex);
- rcu_read_unlock();
return 0;
err:
- rcu_read_unlock();
return -1;
}
@@ -2712,7 +2710,8 @@ static uint64_t ram_bytes_total_common(bool count_ignored)
RAMBlock *block;
uint64_t total = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
+
if (count_ignored) {
RAMBLOCK_FOREACH_MIGRATABLE(block) {
total += block->used_length;
@@ -2722,7 +2721,6 @@ static uint64_t ram_bytes_total_common(bool count_ignored)
total += block->used_length;
}
}
- rcu_read_unlock();
return total;
}
@@ -3086,7 +3084,7 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
RAMBlock *block;
int ret;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
/* This should be our last sync, the src is now paused */
migration_bitmap_sync(rs);
@@ -3107,13 +3105,11 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
* point.
*/
error_report("migration ram resized during precopy phase");
- rcu_read_unlock();
return -EINVAL;
}
/* Deal with TPS != HPS and huge pages */
ret = postcopy_chunk_hostpages(ms, block);
if (ret) {
- rcu_read_unlock();
return ret;
}
@@ -3128,7 +3124,6 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
trace_ram_postcopy_send_discard_bitmap();
ret = postcopy_each_ram_send_discard(ms);
- rcu_read_unlock();
return ret;
}
@@ -3149,7 +3144,7 @@ int ram_discard_range(const char *rbname, uint64_t start, size_t length)
trace_ram_discard_range(rbname, start, length);
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
RAMBlock *rb = qemu_ram_block_by_name(rbname);
if (!rb) {
@@ -3169,8 +3164,6 @@ int ram_discard_range(const char *rbname, uint64_t start, size_t length)
ret = ram_block_discard_range(rb, start, length);
err:
- rcu_read_unlock();
-
return ret;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v2 3/5] migration: Use automatic rcu_read unlock in rdma.c
2019-09-11 19:06 [Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock Dr. David Alan Gilbert (git)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant Dr. David Alan Gilbert (git)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 2/5] migration: Use automatic rcu_read unlock in ram.c Dr. David Alan Gilbert (git)
@ 2019-09-11 19:06 ` Dr. David Alan Gilbert (git)
2019-09-12 9:37 ` Daniel P. Berrangé
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 4/5] rcu: Use automatic rc_read unlock in core memory/exec code Dr. David Alan Gilbert (git)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock Dr. David Alan Gilbert (git)
4 siblings, 1 reply; 17+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-11 19:06 UTC (permalink / raw)
To: qemu-devel, pbonzini, ehabkost, berrange, quintela
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Use the automatic read unlocker in migration/rdma.c.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/rdma.c | 57 ++++++++++--------------------------------------
1 file changed, 11 insertions(+), 46 deletions(-)
diff --git a/migration/rdma.c b/migration/rdma.c
index 78e6b72bac..32c9aba7b3 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -88,7 +88,6 @@ static uint32_t known_capabilities = RDMA_CAPABILITY_PIN_ALL;
" to abort!"); \
rdma->error_reported = 1; \
} \
- rcu_read_unlock(); \
return rdma->error_state; \
} \
} while (0)
@@ -2678,11 +2677,10 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
size_t i;
size_t len = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdma = atomic_rcu_read(&rioc->rdmaout);
if (!rdma) {
- rcu_read_unlock();
return -EIO;
}
@@ -2695,7 +2693,6 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
ret = qemu_rdma_write_flush(f, rdma);
if (ret < 0) {
rdma->error_state = ret;
- rcu_read_unlock();
return ret;
}
@@ -2715,7 +2712,6 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
if (ret < 0) {
rdma->error_state = ret;
- rcu_read_unlock();
return ret;
}
@@ -2724,7 +2720,6 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
}
}
- rcu_read_unlock();
return done;
}
@@ -2764,11 +2759,10 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
ssize_t i;
size_t done = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdma = atomic_rcu_read(&rioc->rdmain);
if (!rdma) {
- rcu_read_unlock();
return -EIO;
}
@@ -2805,7 +2799,6 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
if (ret < 0) {
rdma->error_state = ret;
- rcu_read_unlock();
return ret;
}
@@ -2819,14 +2812,12 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
/* Still didn't get enough, so lets just return */
if (want) {
if (done == 0) {
- rcu_read_unlock();
return QIO_CHANNEL_ERR_BLOCK;
} else {
break;
}
}
}
- rcu_read_unlock();
return done;
}
@@ -2882,7 +2873,7 @@ qio_channel_rdma_source_prepare(GSource *source,
GIOCondition cond = 0;
*timeout = -1;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
if (rsource->condition == G_IO_IN) {
rdma = atomic_rcu_read(&rsource->rioc->rdmain);
} else {
@@ -2891,7 +2882,6 @@ qio_channel_rdma_source_prepare(GSource *source,
if (!rdma) {
error_report("RDMAContext is NULL when prepare Gsource");
- rcu_read_unlock();
return FALSE;
}
@@ -2900,7 +2890,6 @@ qio_channel_rdma_source_prepare(GSource *source,
}
cond |= G_IO_OUT;
- rcu_read_unlock();
return cond & rsource->condition;
}
@@ -2911,7 +2900,7 @@ qio_channel_rdma_source_check(GSource *source)
RDMAContext *rdma;
GIOCondition cond = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
if (rsource->condition == G_IO_IN) {
rdma = atomic_rcu_read(&rsource->rioc->rdmain);
} else {
@@ -2920,7 +2909,6 @@ qio_channel_rdma_source_check(GSource *source)
if (!rdma) {
error_report("RDMAContext is NULL when check Gsource");
- rcu_read_unlock();
return FALSE;
}
@@ -2929,7 +2917,6 @@ qio_channel_rdma_source_check(GSource *source)
}
cond |= G_IO_OUT;
- rcu_read_unlock();
return cond & rsource->condition;
}
@@ -2943,7 +2930,7 @@ qio_channel_rdma_source_dispatch(GSource *source,
RDMAContext *rdma;
GIOCondition cond = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
if (rsource->condition == G_IO_IN) {
rdma = atomic_rcu_read(&rsource->rioc->rdmain);
} else {
@@ -2952,7 +2939,6 @@ qio_channel_rdma_source_dispatch(GSource *source,
if (!rdma) {
error_report("RDMAContext is NULL when dispatch Gsource");
- rcu_read_unlock();
return FALSE;
}
@@ -2961,7 +2947,6 @@ qio_channel_rdma_source_dispatch(GSource *source,
}
cond |= G_IO_OUT;
- rcu_read_unlock();
return (*func)(QIO_CHANNEL(rsource->rioc),
(cond & rsource->condition),
user_data);
@@ -3058,7 +3043,7 @@ qio_channel_rdma_shutdown(QIOChannel *ioc,
QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
RDMAContext *rdmain, *rdmaout;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdmain = atomic_rcu_read(&rioc->rdmain);
rdmaout = atomic_rcu_read(&rioc->rdmain);
@@ -3085,7 +3070,6 @@ qio_channel_rdma_shutdown(QIOChannel *ioc,
break;
}
- rcu_read_unlock();
return 0;
}
@@ -3131,18 +3115,16 @@ static size_t qemu_rdma_save_page(QEMUFile *f, void *opaque,
RDMAContext *rdma;
int ret;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdma = atomic_rcu_read(&rioc->rdmaout);
if (!rdma) {
- rcu_read_unlock();
return -EIO;
}
CHECK_ERROR_STATE();
if (migration_in_postcopy()) {
- rcu_read_unlock();
return RAM_SAVE_CONTROL_NOT_SUPP;
}
@@ -3227,11 +3209,9 @@ static size_t qemu_rdma_save_page(QEMUFile *f, void *opaque,
}
}
- rcu_read_unlock();
return RAM_SAVE_CONTROL_DELAYED;
err:
rdma->error_state = ret;
- rcu_read_unlock();
return ret;
}
@@ -3451,11 +3431,10 @@ static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque)
int count = 0;
int i = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdma = atomic_rcu_read(&rioc->rdmain);
if (!rdma) {
- rcu_read_unlock();
return -EIO;
}
@@ -3698,7 +3677,6 @@ out:
if (ret < 0) {
rdma->error_state = ret;
}
- rcu_read_unlock();
return ret;
}
@@ -3716,11 +3694,10 @@ rdma_block_notification_handle(QIOChannelRDMA *rioc, const char *name)
int curr;
int found = -1;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdma = atomic_rcu_read(&rioc->rdmain);
if (!rdma) {
- rcu_read_unlock();
return -EIO;
}
@@ -3734,7 +3711,6 @@ rdma_block_notification_handle(QIOChannelRDMA *rioc, const char *name)
if (found == -1) {
error_report("RAMBlock '%s' not found on destination", name);
- rcu_read_unlock();
return -ENOENT;
}
@@ -3742,7 +3718,6 @@ rdma_block_notification_handle(QIOChannelRDMA *rioc, const char *name)
trace_rdma_block_notification_handle(name, rdma->next_src_index);
rdma->next_src_index++;
- rcu_read_unlock();
return 0;
}
@@ -3767,17 +3742,15 @@ static int qemu_rdma_registration_start(QEMUFile *f, void *opaque,
QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(opaque);
RDMAContext *rdma;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdma = atomic_rcu_read(&rioc->rdmaout);
if (!rdma) {
- rcu_read_unlock();
return -EIO;
}
CHECK_ERROR_STATE();
if (migration_in_postcopy()) {
- rcu_read_unlock();
return 0;
}
@@ -3785,7 +3758,6 @@ static int qemu_rdma_registration_start(QEMUFile *f, void *opaque,
qemu_put_be64(f, RAM_SAVE_FLAG_HOOK);
qemu_fflush(f);
- rcu_read_unlock();
return 0;
}
@@ -3802,17 +3774,15 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
RDMAControlHeader head = { .len = 0, .repeat = 1 };
int ret = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
rdma = atomic_rcu_read(&rioc->rdmaout);
if (!rdma) {
- rcu_read_unlock();
return -EIO;
}
CHECK_ERROR_STATE();
if (migration_in_postcopy()) {
- rcu_read_unlock();
return 0;
}
@@ -3844,7 +3814,6 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
qemu_rdma_reg_whole_ram_blocks : NULL);
if (ret < 0) {
ERROR(errp, "receiving remote info!");
- rcu_read_unlock();
return ret;
}
@@ -3868,7 +3837,6 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
"not identical on both the source and destination.",
local->nb_blocks, nb_dest_blocks);
rdma->error_state = -EINVAL;
- rcu_read_unlock();
return -EINVAL;
}
@@ -3885,7 +3853,6 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
local->block[i].length,
rdma->dest_blocks[i].length);
rdma->error_state = -EINVAL;
- rcu_read_unlock();
return -EINVAL;
}
local->block[i].remote_host_addr =
@@ -3903,11 +3870,9 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
goto err;
}
- rcu_read_unlock();
return 0;
err:
rdma->error_state = ret;
- rcu_read_unlock();
return ret;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v2 4/5] rcu: Use automatic rc_read unlock in core memory/exec code
2019-09-11 19:06 [Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock Dr. David Alan Gilbert (git)
` (2 preceding siblings ...)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 3/5] migration: Use automatic rcu_read unlock in rdma.c Dr. David Alan Gilbert (git)
@ 2019-09-11 19:06 ` Dr. David Alan Gilbert (git)
2019-09-12 9:38 ` Daniel P. Berrangé
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock Dr. David Alan Gilbert (git)
4 siblings, 1 reply; 17+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-11 19:06 UTC (permalink / raw)
To: qemu-devel, pbonzini, ehabkost, berrange, quintela
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Only in the cases where nothing else interesting happens
after the unlock.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
exec.c | 46 +++++++++++++----------------------------
include/exec/ram_addr.h | 8 ++-----
memory.c | 15 +++++---------
3 files changed, 21 insertions(+), 48 deletions(-)
diff --git a/exec.c b/exec.c
index 235d6bc883..ac3d933e1a 100644
--- a/exec.c
+++ b/exec.c
@@ -1034,16 +1034,14 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
return;
}
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
mr = address_space_translate(as, addr, &addr, &l, false, attrs);
if (!(memory_region_is_ram(mr)
|| memory_region_is_romd(mr))) {
- rcu_read_unlock();
return;
}
ram_addr = memory_region_get_ram_addr(mr) + addr;
tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
- rcu_read_unlock();
}
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
@@ -1329,14 +1327,13 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length)
end = TARGET_PAGE_ALIGN(start + length);
start &= TARGET_PAGE_MASK;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
block = qemu_get_ram_block(start);
assert(block == qemu_get_ram_block(end - 1));
start1 = (uintptr_t)ramblock_ptr(block, start - block->offset);
CPU_FOREACH(cpu) {
tlb_reset_dirty(cpu, start1, length);
}
- rcu_read_unlock();
}
/* Note: start and end must be within the same ram block. */
@@ -1661,7 +1658,7 @@ void ram_block_dump(Monitor *mon)
RAMBlock *block;
char *psize;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
monitor_printf(mon, "%24s %8s %18s %18s %18s\n",
"Block Name", "PSize", "Offset", "Used", "Total");
RAMBLOCK_FOREACH(block) {
@@ -1673,7 +1670,6 @@ void ram_block_dump(Monitor *mon)
(uint64_t)block->max_length);
g_free(psize);
}
- rcu_read_unlock();
}
#ifdef __linux__
@@ -1995,11 +1991,10 @@ static unsigned long last_ram_page(void)
RAMBlock *block;
ram_addr_t last = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
RAMBLOCK_FOREACH(block) {
last = MAX(last, block->offset + block->max_length);
}
- rcu_read_unlock();
return last >> TARGET_PAGE_BITS;
}
@@ -2086,7 +2081,7 @@ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
}
pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
RAMBLOCK_FOREACH(block) {
if (block != new_block &&
!strcmp(block->idstr, new_block->idstr)) {
@@ -2095,7 +2090,6 @@ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
abort();
}
}
- rcu_read_unlock();
}
/* Called with iothread lock held. */
@@ -2637,17 +2631,16 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
if (xen_enabled()) {
ram_addr_t ram_addr;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
ram_addr = xen_ram_addr_from_mapcache(ptr);
block = qemu_get_ram_block(ram_addr);
if (block) {
*offset = ram_addr - block->offset;
}
- rcu_read_unlock();
return block;
}
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
block = atomic_rcu_read(&ram_list.mru_block);
if (block && block->host && host - block->host < block->max_length) {
goto found;
@@ -2663,7 +2656,6 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
}
}
- rcu_read_unlock();
return NULL;
found:
@@ -2671,7 +2663,6 @@ found:
if (round_offset) {
*offset &= TARGET_PAGE_MASK;
}
- rcu_read_unlock();
return block;
}
@@ -3380,10 +3371,9 @@ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
FlatView *fv;
if (len > 0) {
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
fv = address_space_to_flatview(as);
result = flatview_read(fv, addr, attrs, buf, len);
- rcu_read_unlock();
}
return result;
@@ -3397,10 +3387,9 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
FlatView *fv;
if (len > 0) {
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
fv = address_space_to_flatview(as);
result = flatview_write(fv, addr, attrs, buf, len);
- rcu_read_unlock();
}
return result;
@@ -3440,7 +3429,7 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as,
hwaddr addr1;
MemoryRegion *mr;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
while (len > 0) {
l = len;
mr = address_space_translate(as, addr, &addr1, &l, true, attrs);
@@ -3465,7 +3454,6 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as,
buf += l;
addr += l;
}
- rcu_read_unlock();
return MEMTX_OK;
}
@@ -3610,10 +3598,9 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
FlatView *fv;
bool result;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
fv = address_space_to_flatview(as);
result = flatview_access_valid(fv, addr, len, is_write, attrs);
- rcu_read_unlock();
return result;
}
@@ -3668,13 +3655,12 @@ void *address_space_map(AddressSpace *as,
}
l = len;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
fv = address_space_to_flatview(as);
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
if (!memory_access_is_direct(mr, is_write)) {
if (atomic_xchg(&bounce.in_use, true)) {
- rcu_read_unlock();
return NULL;
}
/* Avoid unbounded allocations */
@@ -3690,7 +3676,6 @@ void *address_space_map(AddressSpace *as,
bounce.buffer, l);
}
- rcu_read_unlock();
*plen = l;
return bounce.buffer;
}
@@ -3700,7 +3685,6 @@ void *address_space_map(AddressSpace *as,
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
l, is_write, attrs);
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
- rcu_read_unlock();
return ptr;
}
@@ -3968,13 +3952,12 @@ bool cpu_physical_memory_is_io(hwaddr phys_addr)
hwaddr l = 1;
bool res;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
mr = address_space_translate(&address_space_memory,
phys_addr, &phys_addr, &l, false,
MEMTXATTRS_UNSPECIFIED);
res = !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
- rcu_read_unlock();
return res;
}
@@ -3983,14 +3966,13 @@ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque)
RAMBlock *block;
int ret = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
RAMBLOCK_FOREACH(block) {
ret = func(block, opaque);
if (ret) {
break;
}
}
- rcu_read_unlock();
return ret;
}
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index a327a80cfe..38f3aaffbd 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -240,7 +240,7 @@ static inline bool cpu_physical_memory_all_dirty(ram_addr_t start,
end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
page = start >> TARGET_PAGE_BITS;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
blocks = atomic_rcu_read(&ram_list.dirty_memory[client]);
@@ -262,8 +262,6 @@ static inline bool cpu_physical_memory_all_dirty(ram_addr_t start,
base += DIRTY_MEMORY_BLOCK_SIZE;
}
- rcu_read_unlock();
-
return dirty;
}
@@ -315,13 +313,11 @@ static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,
idx = page / DIRTY_MEMORY_BLOCK_SIZE;
offset = page % DIRTY_MEMORY_BLOCK_SIZE;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
blocks = atomic_rcu_read(&ram_list.dirty_memory[client]);
set_bit_atomic(offset, blocks->blocks[idx]);
-
- rcu_read_unlock();
}
static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
diff --git a/memory.c b/memory.c
index 61a254c3f9..5bdde7cebb 100644
--- a/memory.c
+++ b/memory.c
@@ -799,14 +799,13 @@ FlatView *address_space_get_flatview(AddressSpace *as)
{
FlatView *view;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
do {
view = address_space_to_flatview(as);
/* If somebody has replaced as->current_map concurrently,
* flatview_ref returns false.
*/
} while (!flatview_ref(view));
- rcu_read_unlock();
return view;
}
@@ -2177,12 +2176,11 @@ int memory_region_get_fd(MemoryRegion *mr)
{
int fd;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
while (mr->alias) {
mr = mr->alias;
}
fd = mr->ram_block->fd;
- rcu_read_unlock();
return fd;
}
@@ -2192,14 +2190,13 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
void *ptr;
uint64_t offset = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
while (mr->alias) {
offset += mr->alias_offset;
mr = mr->alias;
}
assert(mr->ram_block);
ptr = qemu_map_ram_ptr(mr->ram_block, offset);
- rcu_read_unlock();
return ptr;
}
@@ -2589,12 +2586,11 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
hwaddr addr, uint64_t size)
{
MemoryRegionSection ret;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
ret = memory_region_find_rcu(mr, addr, size);
if (ret.mr) {
memory_region_ref(ret.mr);
}
- rcu_read_unlock();
return ret;
}
@@ -2602,9 +2598,8 @@ bool memory_region_present(MemoryRegion *container, hwaddr addr)
{
MemoryRegion *mr;
- rcu_read_lock();
+ RCU_READ_LOCK_AUTO;
mr = memory_region_find_rcu(container, addr, 1).mr;
- rcu_read_unlock();
return mr && mr != container;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock
2019-09-11 19:06 [Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock Dr. David Alan Gilbert (git)
` (3 preceding siblings ...)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 4/5] rcu: Use automatic rc_read unlock in core memory/exec code Dr. David Alan Gilbert (git)
@ 2019-09-11 19:06 ` Dr. David Alan Gilbert (git)
2019-09-12 9:38 ` Daniel P. Berrangé
2019-09-12 12:32 ` Paolo Bonzini
4 siblings, 2 replies; 17+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-11 19:06 UTC (permalink / raw)
To: qemu-devel, pbonzini, ehabkost, berrange, quintela
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Error path missing an unlock.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/ram.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/migration/ram.c b/migration/ram.c
index 1bb82acfe0..977172ea7e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3445,6 +3445,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
RAMBLOCK_FOREACH_MIGRATABLE(block) {
if (!block->idstr[0]) {
error_report("%s: RAMBlock with empty name", __func__);
+ rcu_read_unlock();
return -1;
}
qemu_put_byte(f, strlen(block->idstr));
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant Dr. David Alan Gilbert (git)
@ 2019-09-12 9:35 ` Daniel P. Berrangé
2019-09-12 12:30 ` Paolo Bonzini
1 sibling, 0 replies; 17+ messages in thread
From: Daniel P. Berrangé @ 2019-09-12 9:35 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git); +Cc: pbonzini, quintela, qemu-devel, ehabkost
On Wed, Sep 11, 2019 at 08:06:18PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> RCU_READ_LOCK_AUTO takes the rcu_read_lock and then uses glib's
> g_auto infrastructure (and thus whatever the compiler's hooks are) to
> release it on all exits of the block.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> include/qemu/rcu.h | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/5] migration: Use automatic rcu_read unlock in ram.c
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 2/5] migration: Use automatic rcu_read unlock in ram.c Dr. David Alan Gilbert (git)
@ 2019-09-12 9:37 ` Daniel P. Berrangé
0 siblings, 0 replies; 17+ messages in thread
From: Daniel P. Berrangé @ 2019-09-12 9:37 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git); +Cc: pbonzini, quintela, qemu-devel, ehabkost
On Wed, Sep 11, 2019 at 08:06:19PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Use the automatic read unlocker in migration/ram.c;
> only for the cases where the unlock is at the end of the function.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> migration/ram.c | 25 +++++++++----------------
> 1 file changed, 9 insertions(+), 16 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 3/5] migration: Use automatic rcu_read unlock in rdma.c
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 3/5] migration: Use automatic rcu_read unlock in rdma.c Dr. David Alan Gilbert (git)
@ 2019-09-12 9:37 ` Daniel P. Berrangé
0 siblings, 0 replies; 17+ messages in thread
From: Daniel P. Berrangé @ 2019-09-12 9:37 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git); +Cc: pbonzini, quintela, qemu-devel, ehabkost
On Wed, Sep 11, 2019 at 08:06:20PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Use the automatic read unlocker in migration/rdma.c.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> migration/rdma.c | 57 ++++++++++--------------------------------------
> 1 file changed, 11 insertions(+), 46 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 4/5] rcu: Use automatic rc_read unlock in core memory/exec code
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 4/5] rcu: Use automatic rc_read unlock in core memory/exec code Dr. David Alan Gilbert (git)
@ 2019-09-12 9:38 ` Daniel P. Berrangé
0 siblings, 0 replies; 17+ messages in thread
From: Daniel P. Berrangé @ 2019-09-12 9:38 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git); +Cc: pbonzini, quintela, qemu-devel, ehabkost
On Wed, Sep 11, 2019 at 08:06:21PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Only in the cases where nothing else interesting happens
> after the unlock.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> exec.c | 46 +++++++++++++----------------------------
> include/exec/ram_addr.h | 8 ++-----
> memory.c | 15 +++++---------
> 3 files changed, 21 insertions(+), 48 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock Dr. David Alan Gilbert (git)
@ 2019-09-12 9:38 ` Daniel P. Berrangé
2019-09-12 12:32 ` Paolo Bonzini
1 sibling, 0 replies; 17+ messages in thread
From: Daniel P. Berrangé @ 2019-09-12 9:38 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git); +Cc: pbonzini, quintela, qemu-devel, ehabkost
On Wed, Sep 11, 2019 at 08:06:22PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Error path missing an unlock.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> migration/ram.c | 1 +
> 1 file changed, 1 insertion(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant Dr. David Alan Gilbert (git)
2019-09-12 9:35 ` Daniel P. Berrangé
@ 2019-09-12 12:30 ` Paolo Bonzini
2019-09-12 17:45 ` Dr. David Alan Gilbert
1 sibling, 1 reply; 17+ messages in thread
From: Paolo Bonzini @ 2019-09-12 12:30 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git), qemu-devel, ehabkost, berrange, quintela
On 11/09/19 21:06, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> RCU_READ_LOCK_AUTO takes the rcu_read_lock and then uses glib's
> g_auto infrastructure (and thus whatever the compiler's hooks are) to
> release it on all exits of the block.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> include/qemu/rcu.h | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
> index 22876d1428..8768a7b60a 100644
> --- a/include/qemu/rcu.h
> +++ b/include/qemu/rcu.h
> @@ -154,6 +154,24 @@ extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func);
> }), \
> (RCUCBFunc *)g_free);
>
> +typedef void RCUReadAuto;
> +static inline RCUReadAuto *rcu_read_auto_lock(void)
> +{
> + rcu_read_lock();
> + /* Anything non-NULL causes the cleanup function to be called */
> + return (void *)0x1;
Doesn't this cause a warning (should be "(void *)(uintptr_t)1" instead)?
> +}
> +
> +static inline void rcu_read_auto_unlock(RCUReadAuto *r)
> +{
> + rcu_read_unlock();
> +}
> +
> +G_DEFINE_AUTOPTR_CLEANUP_FUNC(RCUReadAuto, rcu_read_auto_unlock)
> +
> +#define RCU_READ_LOCK_AUTO \
> + g_autoptr(RCUReadAuto) _rcu_read_auto = rcu_read_auto_lock()
> +
> #ifdef __cplusplus
> }
> #endif
>
Is it possible to make this a scope, like
WITH_RCU_READ_LOCK() {
}
? Perhaps something like
#define WITH_RCU_READ_LOCK() \
WITH_RCU_READ_LOCK_(_rcu_read_auto##__COUNTER__)
#define WITH_RCU_READ_LOCK_(var) \
for (g_autoptr(RCUReadAuto) var = rcu_read_auto_lock();
(var); rcu_read_auto_unlock(), (var) = NULL)
where the dummy variable doubles as an execute-once guard and the gauto
cleanup is still used in case of a "break". I'm not sure if the above
raises a warning because of the variable declaration inside the for
loop, though.
Thanks,
Paolo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock Dr. David Alan Gilbert (git)
2019-09-12 9:38 ` Daniel P. Berrangé
@ 2019-09-12 12:32 ` Paolo Bonzini
1 sibling, 0 replies; 17+ messages in thread
From: Paolo Bonzini @ 2019-09-12 12:32 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git), qemu-devel, ehabkost, berrange, quintela
On 11/09/19 21:06, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Error path missing an unlock.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> migration/ram.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/migration/ram.c b/migration/ram.c
> index 1bb82acfe0..977172ea7e 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -3445,6 +3445,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
> RAMBLOCK_FOREACH_MIGRATABLE(block) {
> if (!block->idstr[0]) {
> error_report("%s: RAMBlock with empty name", __func__);
> + rcu_read_unlock();
> return -1;
> }
> qemu_put_byte(f, strlen(block->idstr));
>
(The scoped version would be useful here).
Paolo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant
2019-09-12 12:30 ` Paolo Bonzini
@ 2019-09-12 17:45 ` Dr. David Alan Gilbert
2019-09-13 7:13 ` Paolo Bonzini
0 siblings, 1 reply; 17+ messages in thread
From: Dr. David Alan Gilbert @ 2019-09-12 17:45 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: quintela, berrange, qemu-devel, ehabkost
* Paolo Bonzini (pbonzini@redhat.com) wrote:
> On 11/09/19 21:06, Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> >
> > RCU_READ_LOCK_AUTO takes the rcu_read_lock and then uses glib's
> > g_auto infrastructure (and thus whatever the compiler's hooks are) to
> > release it on all exits of the block.
> >
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > ---
> > include/qemu/rcu.h | 18 ++++++++++++++++++
> > 1 file changed, 18 insertions(+)
> >
> > diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
> > index 22876d1428..8768a7b60a 100644
> > --- a/include/qemu/rcu.h
> > +++ b/include/qemu/rcu.h
> > @@ -154,6 +154,24 @@ extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func);
> > }), \
> > (RCUCBFunc *)g_free);
> >
> > +typedef void RCUReadAuto;
> > +static inline RCUReadAuto *rcu_read_auto_lock(void)
> > +{
> > + rcu_read_lock();
> > + /* Anything non-NULL causes the cleanup function to be called */
> > + return (void *)0x1;
>
> Doesn't this cause a warning (should be "(void *)(uintptr_t)1" instead)?
Apparently not, but I'll change it anyway.
> > +}
> > +
> > +static inline void rcu_read_auto_unlock(RCUReadAuto *r)
> > +{
> > + rcu_read_unlock();
> > +}
> > +
> > +G_DEFINE_AUTOPTR_CLEANUP_FUNC(RCUReadAuto, rcu_read_auto_unlock)
> > +
> > +#define RCU_READ_LOCK_AUTO \
> > + g_autoptr(RCUReadAuto) _rcu_read_auto = rcu_read_auto_lock()
> > +
> > #ifdef __cplusplus
> > }
> > #endif
> >
>
> Is it possible to make this a scope, like
>
> WITH_RCU_READ_LOCK() {
> }
>
> ? Perhaps something like
>
> #define WITH_RCU_READ_LOCK() \
> WITH_RCU_READ_LOCK_(_rcu_read_auto##__COUNTER__)
>
> #define WITH_RCU_READ_LOCK_(var) \
> for (g_autoptr(RCUReadAuto) var = rcu_read_auto_lock();
> (var); rcu_read_auto_unlock(), (var) = NULL)
>
> where the dummy variable doubles as an execute-once guard and the gauto
> cleanup is still used in case of a "break". I'm not sure if the above
> raises a warning because of the variable declaration inside the for
> loop, though.
Yes, that works - I'm not seeing any warnings.
Do you think it's best to use the block version for all cases
or to use the non-block version by taste?
The block version is quite nice, but that turns most of the patches
into 'indent everything'.
Dave
> Thanks,
>
> Paolo
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant
2019-09-12 17:45 ` Dr. David Alan Gilbert
@ 2019-09-13 7:13 ` Paolo Bonzini
2019-09-13 10:24 ` Dr. David Alan Gilbert
0 siblings, 1 reply; 17+ messages in thread
From: Paolo Bonzini @ 2019-09-13 7:13 UTC (permalink / raw)
To: Dr. David Alan Gilbert; +Cc: quintela, berrange, qemu-devel, ehabkost
On 12/09/19 19:45, Dr. David Alan Gilbert wrote:
> Do you think it's best to use the block version for all cases
> or to use the non-block version by taste?
> The block version is quite nice, but that turns most of the patches
> into 'indent everything'.
I don't really know myself.
On first glance I didn't like too much the non-block version and thought
it was because our coding standards does not include variables declared
in the middle of a block. However, I think what really bothering me is
"AUTO" in the name. What do you think about "RCU_READ_LOCK_GUARD()"?
The block version would have the additional prefix "WITH_".
We could also add LOCK_GUARD(lock) and WITH_LOCK_GUARD(lock), using
QemuLockable for polymorphism. I even had patches a while ago (though
they used something like LOCK_GUARD(guard_var, lock). I think we
dropped them because of fear that the API was a bit over-engineered.
Paolo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant
2019-09-13 7:13 ` Paolo Bonzini
@ 2019-09-13 10:24 ` Dr. David Alan Gilbert
2019-09-13 10:29 ` Paolo Bonzini
0 siblings, 1 reply; 17+ messages in thread
From: Dr. David Alan Gilbert @ 2019-09-13 10:24 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: quintela, berrange, qemu-devel, ehabkost
* Paolo Bonzini (pbonzini@redhat.com) wrote:
> On 12/09/19 19:45, Dr. David Alan Gilbert wrote:
> > Do you think it's best to use the block version for all cases
> > or to use the non-block version by taste?
> > The block version is quite nice, but that turns most of the patches
> > into 'indent everything'.
>
> I don't really know myself.
OK, new version coming up with a mix - the diffs do look a lot more
hectic with the block version.
> On first glance I didn't like too much the non-block version and thought
> it was because our coding standards does not include variables declared
> in the middle of a block.
I took that as being a coding standard to avoid confusing humans and
since it wasn't visible it didn't matter too much.
> However, I think what really bothering me is
> "AUTO" in the name. What do you think about "RCU_READ_LOCK_GUARD()"?
> The block version would have the additional prefix "WITH_".
Oh well, if it's just the name we can fix that.
> We could also add LOCK_GUARD(lock) and WITH_LOCK_GUARD(lock), using
> QemuLockable for polymorphism. I even had patches a while ago (though
> they used something like LOCK_GUARD(guard_var, lock). I think we
> dropped them because of fear that the API was a bit over-engineered.
Probably a separate set.
Dave
> Paolo
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant
2019-09-13 10:24 ` Dr. David Alan Gilbert
@ 2019-09-13 10:29 ` Paolo Bonzini
0 siblings, 0 replies; 17+ messages in thread
From: Paolo Bonzini @ 2019-09-13 10:29 UTC (permalink / raw)
To: Dr. David Alan Gilbert; +Cc: quintela, berrange, qemu-devel, ehabkost
On 13/09/19 12:24, Dr. David Alan Gilbert wrote:
>> We could also add LOCK_GUARD(lock) and WITH_LOCK_GUARD(lock), using
>> QemuLockable for polymorphism. I even had patches a while ago (though
>> they used something like LOCK_GUARD(guard_var, lock). I think we
>> dropped them because of fear that the API was a bit over-engineered.
> Probably a separate set.
Definitely so. Thanks!
Paolo
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2019-09-13 10:33 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-11 19:06 [Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock Dr. David Alan Gilbert (git)
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant Dr. David Alan Gilbert (git)
2019-09-12 9:35 ` Daniel P. Berrangé
2019-09-12 12:30 ` Paolo Bonzini
2019-09-12 17:45 ` Dr. David Alan Gilbert
2019-09-13 7:13 ` Paolo Bonzini
2019-09-13 10:24 ` Dr. David Alan Gilbert
2019-09-13 10:29 ` Paolo Bonzini
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 2/5] migration: Use automatic rcu_read unlock in ram.c Dr. David Alan Gilbert (git)
2019-09-12 9:37 ` Daniel P. Berrangé
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 3/5] migration: Use automatic rcu_read unlock in rdma.c Dr. David Alan Gilbert (git)
2019-09-12 9:37 ` Daniel P. Berrangé
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 4/5] rcu: Use automatic rc_read unlock in core memory/exec code Dr. David Alan Gilbert (git)
2019-09-12 9:38 ` Daniel P. Berrangé
2019-09-11 19:06 ` [Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock Dr. David Alan Gilbert (git)
2019-09-12 9:38 ` Daniel P. Berrangé
2019-09-12 12:32 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).