From: Peter Xu <peterx@redhat.com>
To: Fabiano Rosas <farosas@suse.de>
Cc: qemu-devel@nongnu.org, berrange@redhat.com, armbru@redhat.com,
Juan Quintela <quintela@redhat.com>,
Leonardo Bras <leobras@redhat.com>,
Claudio Fontana <cfontana@suse.de>,
Nikolay Borisov <nborisov@suse.com>
Subject: Re: [RFC PATCH v3 09/30] migration/ram: Add incoming 'fixed-ram' migration
Date: Mon, 15 Jan 2024 17:49:52 +0800 [thread overview]
Message-ID: <ZaT_wLbb9fZVauia@x1n> (raw)
In-Reply-To: <20231127202612.23012-10-farosas@suse.de>
On Mon, Nov 27, 2023 at 05:25:51PM -0300, Fabiano Rosas wrote:
> Add the necessary code to parse the format changes for the 'fixed-ram'
> capability.
>
> One of the more notable changes in behavior is that in the 'fixed-ram'
> case ram pages are restored in one go rather than constantly looping
> through the migration stream.
>
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> - added sanity check for pages_offset alignment
> - s/parsing/reading
> - used Error
> - fixed buffer size computation, now allowing an arbitrary limit
> - fixed dereference of pointer to packed struct member in endianness
> conversion
> ---
> migration/ram.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 119 insertions(+)
>
> diff --git a/migration/ram.c b/migration/ram.c
> index 4a0ab8105f..08604222f2 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -106,6 +106,12 @@
> */
> #define FIXED_RAM_FILE_OFFSET_ALIGNMENT 0x100000
>
> +/*
> + * When doing fixed-ram migration, this is the amount we read from the
> + * pages region in the migration file at a time.
> + */
> +#define FIXED_RAM_LOAD_BUF_SIZE 0x100000
> +
> XBZRLECacheStats xbzrle_counters;
>
> /* used by the search for pages to send */
> @@ -2996,6 +3002,35 @@ static void fixed_ram_insert_header(QEMUFile *file, RAMBlock *block)
> qemu_put_buffer(file, (uint8_t *) header, header_size);
> }
>
> +static bool fixed_ram_read_header(QEMUFile *file, FixedRamHeader *header,
> + Error **errp)
> +{
> + size_t ret, header_size = sizeof(FixedRamHeader);
> +
> + ret = qemu_get_buffer(file, (uint8_t *)header, header_size);
> + if (ret != header_size) {
> + error_setg(errp, "Could not read whole fixed-ram migration header "
> + "(expected %zd, got %zd bytes)", header_size, ret);
> + return false;
> + }
> +
> + /* migration stream is big-endian */
> + header->version = be32_to_cpu(header->version);
> +
> + if (header->version > FIXED_RAM_HDR_VERSION) {
> + error_setg(errp, "Migration fixed-ram capability version mismatch "
> + "(expected %d, got %d)", FIXED_RAM_HDR_VERSION,
> + header->version);
> + return false;
> + }
> +
> + header->page_size = be64_to_cpu(header->page_size);
> + header->bitmap_offset = be64_to_cpu(header->bitmap_offset);
> + header->pages_offset = be64_to_cpu(header->pages_offset);
> +
> + return true;
> +}
> +
> /*
> * Each of ram_save_setup, ram_save_iterate and ram_save_complete has
> * long-running RCU critical section. When rcu-reclaims in the code
> @@ -3892,6 +3927,80 @@ void colo_flush_ram_cache(void)
> trace_colo_flush_ram_cache_end();
> }
>
> +static void read_ramblock_fixed_ram(QEMUFile *f, RAMBlock *block,
> + long num_pages, unsigned long *bitmap)
> +{
> + unsigned long set_bit_idx, clear_bit_idx;
> + ram_addr_t offset;
> + void *host;
> + size_t read, unread, size, buf_size = FIXED_RAM_LOAD_BUF_SIZE;
> +
> + for (set_bit_idx = find_first_bit(bitmap, num_pages);
> + set_bit_idx < num_pages;
> + set_bit_idx = find_next_bit(bitmap, num_pages, clear_bit_idx + 1)) {
> +
> + clear_bit_idx = find_next_zero_bit(bitmap, num_pages, set_bit_idx + 1);
> +
> + unread = TARGET_PAGE_SIZE * (clear_bit_idx - set_bit_idx);
> + offset = set_bit_idx << TARGET_PAGE_BITS;
> +
> + while (unread > 0) {
> + host = host_from_ram_block_offset(block, offset);
> + size = MIN(unread, buf_size);
Use the macro directly? buf_size can be dropped then.
> +
> + read = qemu_get_buffer_at(f, host, size,
> + block->pages_offset + offset);
Error detection missing? qemu_get_buffer_at() returns 0 if error, then it
dead loops.
> + offset += read;
> + unread -= read;
> + }
> + }
> +}
> +
> +static int parse_ramblock_fixed_ram(QEMUFile *f, RAMBlock *block,
> + ram_addr_t length, Error **errp)
For new code, start to keep using boolean as retval when Error** exists?
> +{
> + g_autofree unsigned long *bitmap = NULL;
> + FixedRamHeader header;
> + size_t bitmap_size;
> + long num_pages;
> +
> + if (!fixed_ram_read_header(f, &header, errp)) {
> + return -EINVAL;
> + }
> +
> + block->pages_offset = header.pages_offset;
> +
> + /*
> + * Check the alignment of the file region that contains pages. We
> + * don't enforce FIXED_RAM_FILE_OFFSET_ALIGNMENT to allow that
> + * value to change in the future. Do only a sanity check with page
> + * size alignment.
> + */
> + if (!QEMU_IS_ALIGNED(block->pages_offset, TARGET_PAGE_SIZE)) {
> + error_setg(errp,
> + "Error reading ramblock %s pages, region has bad alignment",
> + block->idstr);
> + return -EINVAL;
> + }
> +
> + num_pages = length / header.page_size;
> + bitmap_size = BITS_TO_LONGS(num_pages) * sizeof(unsigned long);
> +
> + bitmap = g_malloc0(bitmap_size);
> + if (qemu_get_buffer_at(f, (uint8_t *)bitmap, bitmap_size,
> + header.bitmap_offset) != bitmap_size) {
> + error_setg(errp, "Error reading dirty bitmap");
> + return -EINVAL;
> + }
> +
> + read_ramblock_fixed_ram(f, block, num_pages, bitmap);
Detect error and fail properly?
> +
> + /* Skip pages array */
> + qemu_set_offset(f, block->pages_offset + length, SEEK_SET);
> +
> + return 0;
> +}
> +
> static int parse_ramblock(QEMUFile *f, RAMBlock *block, ram_addr_t length)
> {
> int ret = 0;
> @@ -3900,6 +4009,16 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, ram_addr_t length)
>
> assert(block);
>
> + if (migrate_fixed_ram()) {
> + Error *local_err = NULL;
> +
> + ret = parse_ramblock_fixed_ram(f, block, length, &local_err);
> + if (local_err) {
> + error_report_err(local_err);
> + }
> + return ret;
We can optionally add one pre-requisite patch to convert parse_ramblock()
to return boolean too. I remember it was done somewhere before, but maybe
not merged.
> + }
> +
> if (!qemu_ram_is_migratable(block)) {
> error_report("block %s should not be migrated !", block->idstr);
> return -EINVAL;
> --
> 2.35.3
>
--
Peter Xu
next prev parent reply other threads:[~2024-01-15 9:51 UTC|newest]
Thread overview: 95+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-27 20:25 [RFC PATCH v3 00/30] migration: File based migration with multifd and fixed-ram Fabiano Rosas
2023-11-27 20:25 ` [RFC PATCH v3 01/30] io: add and implement QIO_CHANNEL_FEATURE_SEEKABLE for channel file Fabiano Rosas
2024-01-10 8:49 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 02/30] io: Add generic pwritev/preadv interface Fabiano Rosas
2024-01-10 9:07 ` Daniel P. Berrangé
2024-01-11 6:59 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 03/30] io: implement io_pwritev/preadv for QIOChannelFile Fabiano Rosas
2024-01-10 9:08 ` Daniel P. Berrangé
2024-01-11 7:04 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 04/30] io: fsync before closing a file channel Fabiano Rosas
2024-01-10 9:04 ` Daniel P. Berrangé
2024-01-11 8:44 ` Peter Xu
2024-01-11 18:46 ` Fabiano Rosas
2024-01-12 0:01 ` Peter Xu
2024-01-12 10:40 ` Daniel P. Berrangé
2024-01-15 3:38 ` Peter Xu
2024-01-15 8:57 ` Peter Xu
2024-01-15 9:03 ` Daniel P. Berrangé
2024-01-15 9:31 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 05/30] migration/qemu-file: add utility methods for working with seekable channels Fabiano Rosas
2024-01-11 9:57 ` Peter Xu
2024-01-11 18:49 ` Fabiano Rosas
2023-11-27 20:25 ` [RFC PATCH v3 06/30] migration/ram: Introduce 'fixed-ram' migration capability Fabiano Rosas
2023-12-22 10:35 ` Markus Armbruster
2024-01-11 10:43 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 07/30] migration: Add fixed-ram URI compatibility check Fabiano Rosas
2024-01-15 9:01 ` Peter Xu
2024-01-23 19:07 ` Fabiano Rosas
2024-01-23 19:07 ` Fabiano Rosas
2023-11-27 20:25 ` [RFC PATCH v3 08/30] migration/ram: Add outgoing 'fixed-ram' migration Fabiano Rosas
2024-01-15 9:28 ` Peter Xu
2024-01-15 14:50 ` Fabiano Rosas
2023-11-27 20:25 ` [RFC PATCH v3 09/30] migration/ram: Add incoming " Fabiano Rosas
2024-01-15 9:49 ` Peter Xu [this message]
2024-01-15 16:43 ` Fabiano Rosas
2023-11-27 20:25 ` [RFC PATCH v3 10/30] tests/qtest: migration-test: Add tests for fixed-ram file-based migration Fabiano Rosas
2024-01-15 10:01 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 11/30] migration/multifd: Allow multifd without packets Fabiano Rosas
2024-01-15 11:51 ` Peter Xu
2024-01-15 18:39 ` Fabiano Rosas
2024-01-15 23:01 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 12/30] migration/multifd: Allow QIOTask error reporting without an object Fabiano Rosas
2024-01-15 12:06 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 13/30] migration/multifd: Add outgoing QIOChannelFile support Fabiano Rosas
2024-01-16 4:05 ` Peter Xu
2024-01-16 7:25 ` Peter Xu
2024-01-16 13:37 ` Fabiano Rosas
2024-01-17 8:28 ` Peter Xu
2024-01-17 17:34 ` Fabiano Rosas
2024-01-18 7:11 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 14/30] migration/multifd: Add incoming " Fabiano Rosas
2024-01-16 6:29 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 15/30] io: Add a pwritev/preadv version that takes a discontiguous iovec Fabiano Rosas
2024-01-16 6:58 ` Peter Xu
2024-01-16 18:15 ` Fabiano Rosas
2024-01-17 9:48 ` Peter Xu
2024-01-17 18:06 ` Fabiano Rosas
2024-01-18 7:44 ` Peter Xu
2024-01-18 12:47 ` Fabiano Rosas
2024-01-19 0:22 ` Peter Xu
2024-01-17 12:39 ` Daniel P. Berrangé
2024-01-17 14:27 ` Daniel P. Berrangé
2024-01-17 18:09 ` Fabiano Rosas
2023-11-27 20:25 ` [RFC PATCH v3 16/30] multifd: Rename MultiFDSendParams::data to compress_data Fabiano Rosas
2024-01-16 7:03 ` Peter Xu
2023-11-27 20:25 ` [RFC PATCH v3 17/30] migration/multifd: Decouple recv method from pages Fabiano Rosas
2024-01-16 7:23 ` Peter Xu
2023-11-27 20:26 ` [RFC PATCH v3 18/30] migration/multifd: Allow receiving pages without packets Fabiano Rosas
2024-01-16 8:10 ` Peter Xu
2024-01-16 20:25 ` Fabiano Rosas
2024-01-19 0:20 ` Peter Xu
2024-01-19 12:57 ` Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 19/30] migration/ram: Ignore multifd flush when doing fixed-ram migration Fabiano Rosas
2024-01-16 8:23 ` Peter Xu
2024-01-17 18:13 ` Fabiano Rosas
2024-01-19 1:33 ` Peter Xu
2023-11-27 20:26 ` [RFC PATCH v3 20/30] migration/multifd: Support outgoing fixed-ram stream format Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 21/30] migration/multifd: Support incoming " Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 22/30] tests/qtest: Add a multifd + fixed-ram migration test Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 23/30] migration: Add direct-io parameter Fabiano Rosas
2023-12-22 10:38 ` Markus Armbruster
2023-11-27 20:26 ` [RFC PATCH v3 24/30] tests/qtest: Add a test for migration with direct-io and multifd Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 25/30] monitor: Honor QMP request for fd removal immediately Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 26/30] monitor: Extract fdset fd flags comparison into a function Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 27/30] monitor: fdset: Match against O_DIRECT Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 28/30] docs/devel/migration.rst: Document the file transport Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 29/30] migration: Add support for fdset with multifd + file Fabiano Rosas
2023-11-27 20:26 ` [RFC PATCH v3 30/30] tests/qtest: Add a test for fixed-ram with passing of fds Fabiano Rosas
2024-01-11 10:50 ` [RFC PATCH v3 00/30] migration: File based migration with multifd and fixed-ram Peter Xu
2024-01-11 18:38 ` Fabiano Rosas
2024-01-15 6:22 ` Peter Xu
2024-01-15 8:11 ` Daniel P. Berrangé
2024-01-15 8:41 ` Peter Xu
2024-01-15 19:45 ` Fabiano Rosas
2024-01-15 23:20 ` Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZaT_wLbb9fZVauia@x1n \
--to=peterx@redhat.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=cfontana@suse.de \
--cc=farosas@suse.de \
--cc=leobras@redhat.com \
--cc=nborisov@suse.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.