From: Marc-André Lureau <marcandre.lureau@redhat.com>
ram_block_attributes_destroy() was called from reclaim_ramblock(), which
runs as an RCU callback deferred by call_rcu().
However,when the RamDiscardManager is finalized, it will assert that its
source_list is empty in the next commit. Since the RCU callback hasn't
run yet, the source added by ram_block_attributes_create() is still
attached.
Move ram_block_attributes_destroy() into qemu_ram_free() so the source
is removed synchronously. This is safe because qemu_ram_free() during
shutdown runs after pause_all_vcpus(), so no vCPU thread can
concurrently access the attributes via kvm_convert_memory().
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
system/physmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/system/physmem.c b/system/physmem.c
index 2fb0c25c93b..cf64caf6285 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2589,7 +2589,6 @@ static void reclaim_ramblock(RAMBlock *block)
}
if (block->guest_memfd >= 0) {
- ram_block_attributes_destroy(block->attributes);
close(block->guest_memfd);
ram_block_coordinated_discard_require(false);
}
@@ -2618,6 +2617,7 @@ void qemu_ram_free(RAMBlock *block)
/* Write list before version */
smp_wmb();
ram_list.version++;
+ g_clear_pointer(&block->attributes, ram_block_attributes_destroy);
call_rcu(block, reclaim_ramblock, rcu);
qemu_mutex_unlock_ramlist();
}
--
2.53.0