@samitouri / QOSamiQemu / commits / a6f1bc9846

system/physmem: destroy ram block attributes before RCU-deferred reclaim

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(). Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Link: https://lore.kernel.org/r/20260604-rdm5-v5-8-5768e6a0943d@redhat.com [peterx: rebase on top of qemu_ram_free() change] Signed-off-by: Peter Xu <peterx@redhat.com>

Marc-André Lureau committed Jun 4, 2026 at 17:43 UTC a6f1bc9846f7c5e3d7fdc9e1e4bc87a546fa11cb
1 file changed +1 -1
system/physmem.c
+1 -1
@@ -2582,7 +2582,6 @@ static void reclaim_ramblock(RAMBlock *block)
2582 }
2583
2584 if (block->guest_memfd >= 0) {
2585 - ram_block_attributes_destroy(block->attributes);
2585 close(block->guest_memfd);
2586 ram_block_coordinated_discard_require(false);
2587 }
@@ -2610,6 +2609,7 @@ void qemu_ram_free(RAMBlock *block)
2609 qatomic_set(&ram_list.mru_block, NULL);
2610 /* Write list before version */
2611 qatomic_store_release(&ram_list.version, ram_list.version + 1);
2612 + g_clear_pointer(&block->attributes, ram_block_attributes_destroy);
2613 call_rcu(block, reclaim_ramblock, rcu);
2614 qemu_mutex_unlock_ramlist();
2615 }