summaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2026-06-04 17:43:57 +0400
committerPeter Xu <peterx@redhat.com>2026-06-22 17:08:49 -0400
commit1f3241bcaeee0df47f72edf6abad71fe36f3b0e7 (patch)
treea1fcaf2f4f829983e9a4841e1d2866bd5b8cd3a5 /system
parentc2237aaf6dcdef9a9886baee512ca2c43f3fed08 (diff)
downloadqemu-1f3241bcaeee0df47f72edf6abad71fe36f3b0e7.tar.gz
qemu-1f3241bcaeee0df47f72edf6abad71fe36f3b0e7.zip
system/physmem: make ram_block_discard_range() handle guest_memfd
Most callers of ram_block_discard_range() want to discard both the shared and guest_memfd backing. Only kvm_convert_memory() intentionally discards a single plane during private/shared conversions. Rename the current implementation to ram_block_discard_shared_range() and make ram_block_discard_range() a composite that also discards guest_memfd when present (rb->guest_memfd >= 0). This ensures callers like virtio-mem, virtio-balloon, hv-balloon, migration.. reclaim private pages on discard. Update kvm_convert_memory() to use the plane-specific ram_block_discard_shared_range() since it only needs to discard the shared backing when converting to private. Likewise, after TDVF image copy, use ram_block_discard_shared_range(). Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Link: https://lore.kernel.org/r/20260604-rdm5-v5-11-5768e6a0943d@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>
Diffstat (limited to 'system')
-rw-r--r--system/physmem.c25
-rw-r--r--system/trace-events2
2 files changed, 22 insertions, 5 deletions
diff --git a/system/physmem.c b/system/physmem.c
index c4bfb57625..c21ea92915 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -4093,7 +4093,7 @@ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque)
* Returns: 0 on success, none-0 on failure
*
*/
-int ram_block_discard_range(RAMBlock *rb, uint64_t offset, size_t length)
+int ram_block_discard_shared_range(RAMBlock *rb, uint64_t offset, size_t length)
{
int ret = -1;
@@ -4142,7 +4142,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t offset, size_t length)
* have a MAP_PRIVATE mapping, possibly messing with other
* MAP_PRIVATE/MAP_SHARED mappings. There is no easy way to
* change that behavior whithout violating the promised
- * semantics of ram_block_discard_range().
+ * semantics of ram_block_discard_shared_range().
*
* Only warn, because it works as long as nobody else uses that
* file.
@@ -4198,8 +4198,9 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t offset, size_t length)
goto err;
#endif
}
- trace_ram_block_discard_range(rb->idstr, host_startaddr, length,
- need_madvise, need_fallocate, ret);
+ trace_ram_block_discard_shared_range(rb->idstr, host_startaddr, length,
+ need_madvise, need_fallocate,
+ ret);
} else {
error_report("%s: Overrun block '%s' (%" PRIu64 "/%zx/" RAM_ADDR_FMT")",
__func__, rb->idstr, offset, length, rb->max_length);
@@ -4209,6 +4210,22 @@ err:
return ret;
}
+int ram_block_discard_range(RAMBlock *rb, uint64_t offset, size_t length)
+{
+ int ret;
+
+ ret = ram_block_discard_shared_range(rb, offset, length);
+ if (ret) {
+ return ret;
+ }
+
+ if (rb->guest_memfd >= 0) {
+ ret = ram_block_discard_guest_memfd_range(rb, offset, length);
+ }
+
+ return ret;
+}
+
int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t offset,
size_t length)
{
diff --git a/system/trace-events b/system/trace-events
index e6e1b61279..51b4a4679a 100644
--- a/system/trace-events
+++ b/system/trace-events
@@ -32,7 +32,7 @@ global_dirty_changed(unsigned int bitmask) "bitmask 0x%"PRIx32
address_space_map(void *as, uint64_t addr, uint64_t len, bool is_write, uint32_t attrs) "as:%p addr 0x%"PRIx64":%"PRIx64" write:%d attrs:0x%x"
find_ram_offset(uint64_t size, uint64_t offset) "size: 0x%" PRIx64 " @ 0x%" PRIx64
find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, uint64_t next, uint64_t mingap) "trying size: 0x%" PRIx64 " @ 0x%" PRIx64 ", offset: 0x%" PRIx64" next: 0x%" PRIx64 " mingap: 0x%" PRIx64
-ram_block_discard_range(const char *rbname, void *hva, size_t length, bool need_madvise, bool need_fallocate, int ret) "%s@%p + 0x%zx: madvise: %d fallocate: %d ret: %d"
+ram_block_discard_shared_range(const char *rbname, void *hva, size_t length, bool need_madvise, bool need_fallocate, int ret) "%s@%p + 0x%zx: madvise: %d fallocate: %d ret: %d"
qemu_ram_alloc_shared(const char *name, size_t size, size_t max_size, int fd, void *host) "%s size %zu max_size %zu fd %d host %p"
subpage_register(void *subpage, uint32_t start, uint32_t end, int idx, int eidx, uint16_t section) "subpage %p start 0x%08x end 0x%08x idx 0x%08x eidx 0x%08x section %u"