hw/virtio/virtio-balloon.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-)
The balloon inflate/deflate paths obtained the RAMBlock through a
round-trip: compute host VA via memory_region_get_ram_ptr(), then
reverse-lookup via qemu_ram_block_from_host() which linearly scans
the RAMBlock list.
Since memory_region_find() already resolves to the concrete RAM
MemoryRegion (aliases flattened), mr->ram_block is guaranteed valid
and mr_offset directly serves as the RAMBlock offset. Use this to
eliminate the unnecessary VA computation and list walk.
This also removes the long-standing XXX comment asking for a better
approach.
Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
---
hw/virtio/virtio-balloon.c | 30 +++++++++---------------------
1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 4c5f486ba2..4a7f0bb9a8 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -80,21 +80,15 @@ static void balloon_inflate_page(VirtIOBalloon *balloon,
MemoryRegion *mr, hwaddr mr_offset,
PartiallyBalloonedPage *pbp)
{
- void *addr = memory_region_get_ram_ptr(mr) + mr_offset;
- ram_addr_t rb_offset, rb_aligned_offset, base_gpa;
- RAMBlock *rb;
+ RAMBlock *rb = mr->ram_block;
+ ram_addr_t rb_aligned_offset, base_gpa;
size_t rb_page_size;
int subpages;
- /* XXX is there a better way to get to the RAMBlock than via a
- * host address? */
- rb = qemu_ram_block_from_host(addr, false, &rb_offset);
rb_page_size = qemu_ram_pagesize(rb);
if (rb_page_size == BALLOON_PAGE_SIZE) {
- /* Easy case */
-
- ram_block_discard_range(rb, rb_offset, rb_page_size);
+ ram_block_discard_range(rb, mr_offset, rb_page_size);
/* We ignore errors from ram_block_discard_range(), because it
* has already reported them, and failing to discard a balloon
* page is not fatal */
@@ -110,10 +104,9 @@ static void balloon_inflate_page(VirtIOBalloon *balloon,
warn_report_once(
"Balloon used with backing page size > 4kiB, this may not be reliable");
- rb_aligned_offset = QEMU_ALIGN_DOWN(rb_offset, rb_page_size);
+ rb_aligned_offset = QEMU_ALIGN_DOWN(mr_offset, rb_page_size);
subpages = rb_page_size / BALLOON_PAGE_SIZE;
- base_gpa = memory_region_get_ram_addr(mr) + mr_offset -
- (rb_offset - rb_aligned_offset);
+ base_gpa = memory_region_get_ram_addr(mr) + rb_aligned_offset;
if (pbp->bitmap && !virtio_balloon_pbp_matches(pbp, base_gpa)) {
/* We've partially ballooned part of a host page, but now
@@ -126,7 +119,7 @@ static void balloon_inflate_page(VirtIOBalloon *balloon,
virtio_balloon_pbp_alloc(pbp, base_gpa, subpages);
}
- set_bit((rb_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE,
+ set_bit((mr_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE,
pbp->bitmap);
if (bitmap_full(pbp->bitmap, subpages)) {
@@ -144,19 +137,14 @@ static void balloon_inflate_page(VirtIOBalloon *balloon,
static void balloon_deflate_page(VirtIOBalloon *balloon,
MemoryRegion *mr, hwaddr mr_offset)
{
- void *addr = memory_region_get_ram_ptr(mr) + mr_offset;
- ram_addr_t rb_offset;
- RAMBlock *rb;
+ RAMBlock *rb = mr->ram_block;
size_t rb_page_size;
void *host_addr;
int ret;
- /* XXX is there a better way to get to the RAMBlock than via a
- * host address? */
- rb = qemu_ram_block_from_host(addr, false, &rb_offset);
rb_page_size = qemu_ram_pagesize(rb);
-
- host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1));
+ host_addr = qemu_ram_get_host_addr(rb) +
+ QEMU_ALIGN_DOWN(mr_offset, rb_page_size);
/* When a page is deflated, we hint the whole host page it lives
* on, since we can't do anything smaller */
--
2.50.1 (Apple Git-155)
© 2016 - 2026 Red Hat, Inc.