On Tue, Jul 7, 2026 at 12:59 AM Peter Xu <[email protected]> wrote:
>
> On Tue, Jun 30, 2026 at 01:49:36PM +0530, Aadeshveer Singh wrote:
> > Replace the temporary bitmap with the existing file_bmap attribute of
> > the RAMBlock. This acts as a preparatory change for the upcoming fast
> > snapshot load feature.
> >
> > Reusing this bitmap allows the destination to track page types during
> > a postcopy load, enabling faster, direct placement of zero pages.
> >
> > Since file_bmap is currently only utilized during the migration save
> > phase, it can be safely repurposed during the load phase without
> > introducing conflicts.
> >
> > Signed-off-by: Aadeshveer Singh <[email protected]>
> > ---
> > migration/ram.c | 33 +++++++++++++++++++++++++++------
> > 1 file changed, 27 insertions(+), 6 deletions(-)
> >
> > diff --git a/migration/ram.c b/migration/ram.c
> > index fc38ffbf8a..4728f14d73 100644
> > --- a/migration/ram.c
> > +++ b/migration/ram.c
> > @@ -252,6 +252,17 @@ int foreach_not_ignored_block(RAMBlockIterFunc func,
> > void *opaque)
> > return ret;
> > }
> >
> > +static void ramblock_file_bmap_init(void)
> > +{
> > + RAMBlock *rb;
> > +
> > + RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
> > + assert(!rb->file_bmap);
> > + size_t size = rb->max_length >> qemu_target_page_bits();
>
> Hmm, I just notice mapped-ram always use guest psize for its bitmap.. even
> for huge pages. In that case this is correct.
>
> > + rb->file_bmap = bitmap_new(size);
> > + }
> > +}
> > +
> > static void ramblock_recv_map_init(void)
> > {
> > RAMBlock *rb;
> > @@ -3749,6 +3760,9 @@ static int ram_load_setup(QEMUFile *f, void *opaque,
> > Error **errp)
> > {
> > xbzrle_load_setup();
> > ramblock_recv_map_init();
> > + if (migrate_mapped_ram()) {
> > + ramblock_file_bmap_init();
> > + }
> >
> > return 0;
> > }
> > @@ -3766,8 +3780,8 @@ static int ram_load_cleanup(void *opaque)
> > xbzrle_load_cleanup();
> >
> > RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
> > - g_free(rb->receivedmap);
> > - rb->receivedmap = NULL;
> > + g_clear_pointer(&rb->receivedmap, g_free);
> > + g_clear_pointer(&rb->file_bmap, g_free);
> > }
> >
> > return 0;
> > @@ -4142,11 +4156,18 @@ err:
> > static void parse_ramblock_mapped_ram(QEMUFile *f, RAMBlock *block,
> > ram_addr_t length, Error **errp)
> > {
> > - g_autofree unsigned long *bitmap = NULL;
> > MappedRamHeader header;
> > size_t bitmap_size;
> > long num_pages;
> >
> > + if (length > block->max_length) {
> > + error_setg(errp,
> > + "mapped-ram header length %" PRIu64 " exceeds "
> > + "RAMBlock(\"%s\") max_length %" PRIu64,
> > + (uint64_t)length, block->idstr,
> > (uint64_t)block->max_length);
> > + return;
> > + }
> > +
> > if (!mapped_ram_read_header(f, &header, errp)) {
> > return;
> > }
> > @@ -4174,14 +4195,14 @@ static void parse_ramblock_mapped_ram(QEMUFile *f,
> > RAMBlock *block,
> > num_pages = length / header.page_size;
> > bitmap_size = BITS_TO_LONGS(num_pages) * sizeof(unsigned long);
>
> Here I think it would still be good to check the page_size is the same as
> what was expected (in this case, guest page size), otherwise we should fail
> because then the bitmap_size may still be unpredictable and it can cause
> illegal access (beyond the size of bitmap allocated) in worst case.
Hi Peter, thanks for the review,
Currently mapped_ram_read_header() already enforces header->page_size
== TARGET_PAGE_SIZE and will throw error before reaching this point.
However if you would like an explicit check, let me know.
>
>
> Now I start to wonder when you're working on huge pages with the feature,
> did you stick with the bmap having guest page size, or did you modify it to
> be host page size?
>
To maintain consistency across systems and keep it simple I kept the
guest page size and then applied the range check to it.
>
> Thanks,
>
> >
> > - bitmap = g_malloc0(bitmap_size);
> > - if (qemu_get_buffer_at(f, (uint8_t *)bitmap, bitmap_size,
> > + if (qemu_get_buffer_at(f, (uint8_t *)block->file_bmap, bitmap_size,
> > header.bitmap_offset) != bitmap_size) {
> > error_setg(errp, "Error reading dirty bitmap");
> > return;
> > }
> >
> > - if (!read_ramblock_mapped_ram(f, block, num_pages, bitmap, errp)) {
> > + if (!read_ramblock_mapped_ram(f, block, num_pages, block->file_bmap,
> > + errp)) {
> > return;
> > }
> >
> > --
> > 2.54.0
> >
>
> --
> Peter Xu
>