mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
physmem: Support coordinated discarding of RAM with guest_memfd
A new field, attributes, was introduced in RAMBlock to link to a RamBlockAttributes object, which centralizes all guest_memfd related information (such as fd and status bitmap) within a RAMBlock. Create and initialize the RamBlockAttributes object upon ram_block_add(). Meanwhile, register the object in the target RAMBlock's MemoryRegion. After that, guest_memfd-backed RAMBlock is associated with the RamDiscardManager interface, and the users can execute RamDiscardManager specific handling. For example, VFIO will register the RamDiscardListener and get notifications when the state_change() helper invokes. As coordinate discarding of RAM with guest_memfd is now supported, only block uncoordinated discard. Tested-by: Alexey Kardashevskiy <aik@amd.com> Reviewed-by: Alexey Kardashevskiy <aik@amd.com> Acked-by: David Hildenbrand <david@redhat.com> Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com> Link: https://lore.kernel.org/r/20250612082747.51539-6-chenyi.qiang@intel.com Signed-off-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
parent
5d6483edaa
commit
2fde3fb916
3 changed files with 31 additions and 2 deletions
|
@ -3091,6 +3091,15 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
|
|||
addr = memory_region_get_ram_ptr(mr) + section.offset_within_region;
|
||||
rb = qemu_ram_block_from_host(addr, false, &offset);
|
||||
|
||||
ret = ram_block_attributes_state_change(RAM_BLOCK_ATTRIBUTES(mr->rdm),
|
||||
offset, size, to_private);
|
||||
if (ret) {
|
||||
error_report("Failed to notify the listener the state change of "
|
||||
"(0x%"HWADDR_PRIx" + 0x%"HWADDR_PRIx") to %s",
|
||||
start, size, to_private ? "private" : "shared");
|
||||
goto out_unref;
|
||||
}
|
||||
|
||||
if (to_private) {
|
||||
if (rb->page_size != qemu_real_host_page_size()) {
|
||||
/*
|
||||
|
|
|
@ -46,6 +46,7 @@ struct RAMBlock {
|
|||
int fd;
|
||||
uint64_t fd_offset;
|
||||
int guest_memfd;
|
||||
RamBlockAttributes *attributes;
|
||||
size_t page_size;
|
||||
/* dirty bitmap used during migration */
|
||||
unsigned long *bmap;
|
||||
|
|
|
@ -1916,7 +1916,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
|
|||
}
|
||||
assert(new_block->guest_memfd < 0);
|
||||
|
||||
ret = ram_block_discard_require(true);
|
||||
ret = ram_block_coordinated_discard_require(true);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret,
|
||||
"cannot set up private guest memory: discard currently blocked");
|
||||
|
@ -1931,6 +1931,24 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
/*
|
||||
* The attribute bitmap of the RamBlockAttributes is default to
|
||||
* discarded, which mimics the behavior of kvm_set_phys_mem() when it
|
||||
* calls kvm_set_memory_attributes_private(). This leads to a brief
|
||||
* period of inconsistency between the creation of the RAMBlock and its
|
||||
* mapping into the physical address space. However, this is not
|
||||
* problematic, as no users rely on the attribute status to perform
|
||||
* any actions during this interval.
|
||||
*/
|
||||
new_block->attributes = ram_block_attributes_create(new_block);
|
||||
if (!new_block->attributes) {
|
||||
error_setg(errp, "Failed to create ram block attribute");
|
||||
close(new_block->guest_memfd);
|
||||
ram_block_coordinated_discard_require(false);
|
||||
qemu_mutex_unlock_ramlist();
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a specific guest_memfd blocker if a generic one would not be
|
||||
* added by ram_block_add_cpr_blocker.
|
||||
|
@ -2287,8 +2305,9 @@ static void reclaim_ramblock(RAMBlock *block)
|
|||
}
|
||||
|
||||
if (block->guest_memfd >= 0) {
|
||||
ram_block_attributes_destroy(block->attributes);
|
||||
close(block->guest_memfd);
|
||||
ram_block_discard_require(false);
|
||||
ram_block_coordinated_discard_require(false);
|
||||
}
|
||||
|
||||
g_free(block);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue