[PATCH 1/2] migration: track timing and received pages in MigrationIncomingState

Trieu Huynh posted 2 patches 6 days, 3 hours ago
Maintainers: Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>
[PATCH 1/2] migration: track timing and received pages in MigrationIncomingState
Posted by Trieu Huynh 6 days, 3 hours ago
From: Trieu Huynh <vikingtc4@gmail.com>

Add start_time, total_time, received_normal_pages,
received_zero_pages, and received_xbzrle_pages to
MigrationIncomingState.

start_time is recorded when the incoming state transitions to ACTIVE;
total_time is recorded when it transitions to COMPLETED. The page
counters are incremented in ram_load_precopy() as each page type is
received from the source.

These fields will be used by a subsequent patch to populate
fill_destination_migration_info() for the migration COMPLETED case.

Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
---
 migration/migration.c |  2 ++
 migration/migration.h | 17 +++++++++++++++++
 migration/ram.c       |  3 +++
 3 files changed, 22 insertions(+)

diff --git a/migration/migration.c b/migration/migration.c
index 5c9aaa6e58..17c9a8b344 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -726,6 +726,7 @@ static void process_incoming_migration_bh(void *opaque)
      */
     migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
                       MIGRATION_STATUS_COMPLETED);
+    mis->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - mis->start_time;
     migration_incoming_state_destroy();
 }
 
@@ -758,6 +759,7 @@ process_incoming_migration_co(void *opaque)
     migrate_set_state(&mis->state, MIGRATION_STATUS_SETUP,
                       MIGRATION_STATUS_ACTIVE);
 
+    mis->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
     mis->loadvm_co = qemu_coroutine_self();
     ret = qemu_loadvm_state(mis->from_src_file, &local_err);
     mis->loadvm_co = NULL;
diff --git a/migration/migration.h b/migration/migration.h
index b6888daced..cd51ae452c 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -176,6 +176,23 @@ struct MigrationIncomingState {
     /* PostCopyFD's for external userfaultfds & handlers of shared memory */
     GArray   *postcopy_remote_fds;
 
+    /*
+     * Timestamps for reporting migration duration via query-migrate on the
+     * destination. start_time is recorded when the state moves to ACTIVE;
+     * total_time is recorded when it moves to COMPLETED.
+     */
+    int64_t start_time;
+    int64_t total_time;
+
+    /*
+     * Page counters for reporting RAM statistics via query-migrate on the
+     * destination.  Incremented in ram_load_precopy() as each page type
+     * is received.
+     */
+    uint64_t received_normal_pages;
+    uint64_t received_zero_pages;
+    uint64_t received_xbzrle_pages;
+
     MigrationStatus state;
 
     /*
diff --git a/migration/ram.c b/migration/ram.c
index 979751f61b..6646e5daad 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4417,10 +4417,12 @@ static int ram_load_precopy(QEMUFile *f)
                 break;
             }
             ram_handle_zero(host, TARGET_PAGE_SIZE);
+            mis->received_zero_pages++;
             break;
 
         case RAM_SAVE_FLAG_PAGE:
             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
+            mis->received_normal_pages++;
             break;
 
         case RAM_SAVE_FLAG_XBZRLE:
@@ -4430,6 +4432,7 @@ static int ram_load_precopy(QEMUFile *f)
                 ret = -EINVAL;
                 break;
             }
+            mis->received_xbzrle_pages++;
             break;
         case RAM_SAVE_FLAG_MULTIFD_FLUSH:
             multifd_recv_sync_main();
-- 
2.43.0
Re: [PATCH 1/2] migration: track timing and received pages in MigrationIncomingState
Posted by Claudio Fontana 4 days, 6 hours ago
Hello,

On 4/5/26 17:26, Trieu Huynh wrote:
> From: Trieu Huynh <vikingtc4@gmail.com>
> 
> Add start_time, total_time, received_normal_pages,
> received_zero_pages, and received_xbzrle_pages to
> MigrationIncomingState.
> 
> start_time is recorded when the incoming state transitions to ACTIVE;
> total_time is recorded when it transitions to COMPLETED. The page
> counters are incremented in ram_load_precopy() as each page type is
> received from the source.
> 
> These fields will be used by a subsequent patch to populate
> fill_destination_migration_info() for the migration COMPLETED case.
> 
> Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
> ---
>  migration/migration.c |  2 ++
>  migration/migration.h | 17 +++++++++++++++++
>  migration/ram.c       |  3 +++
>  3 files changed, 22 insertions(+)
> 
> diff --git a/migration/migration.c b/migration/migration.c
> index 5c9aaa6e58..17c9a8b344 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -726,6 +726,7 @@ static void process_incoming_migration_bh(void *opaque)
>       */
>      migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
>                        MIGRATION_STATUS_COMPLETED);
> +    mis->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - mis->start_time;
>      migration_incoming_state_destroy();
>  }
>  
> @@ -758,6 +759,7 @@ process_incoming_migration_co(void *opaque)
>      migrate_set_state(&mis->state, MIGRATION_STATUS_SETUP,
>                        MIGRATION_STATUS_ACTIVE);
>  
> +    mis->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
>      mis->loadvm_co = qemu_coroutine_self();
>      ret = qemu_loadvm_state(mis->from_src_file, &local_err);
>      mis->loadvm_co = NULL;
> diff --git a/migration/migration.h b/migration/migration.h
> index b6888daced..cd51ae452c 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -176,6 +176,23 @@ struct MigrationIncomingState {
>      /* PostCopyFD's for external userfaultfds & handlers of shared memory */
>      GArray   *postcopy_remote_fds;
>  
> +    /*
> +     * Timestamps for reporting migration duration via query-migrate on the
> +     * destination. start_time is recorded when the state moves to ACTIVE;
> +     * total_time is recorded when it moves to COMPLETED.
> +     */
> +    int64_t start_time;
> +    int64_t total_time;

nit: since this is a timestamp and these are directly linked to state changes,
why not call these:

int64_t migration_active_ts;
int64_t migration_completed_ts;

or something similar?

Thank you,

Claudio

> +
> +    /*
> +     * Page counters for reporting RAM statistics via query-migrate on the
> +     * destination.  Incremented in ram_load_precopy() as each page type
> +     * is received.
> +     */
> +    uint64_t received_normal_pages;
> +    uint64_t received_zero_pages;
> +    uint64_t received_xbzrle_pages;
> +
>      MigrationStatus state;
>  
>      /*
> diff --git a/migration/ram.c b/migration/ram.c
> index 979751f61b..6646e5daad 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -4417,10 +4417,12 @@ static int ram_load_precopy(QEMUFile *f)
>                  break;
>              }
>              ram_handle_zero(host, TARGET_PAGE_SIZE);
> +            mis->received_zero_pages++;
>              break;
>  
>          case RAM_SAVE_FLAG_PAGE:
>              qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
> +            mis->received_normal_pages++;
>              break;
>  
>          case RAM_SAVE_FLAG_XBZRLE:
> @@ -4430,6 +4432,7 @@ static int ram_load_precopy(QEMUFile *f)
>                  ret = -EINVAL;
>                  break;
>              }
> +            mis->received_xbzrle_pages++;
>              break;
>          case RAM_SAVE_FLAG_MULTIFD_FLUSH:
>              multifd_recv_sync_main();
Re: [PATCH 1/2] migration: track timing and received pages in MigrationIncomingState
Posted by Claudio Fontana 4 days, 6 hours ago
On 4/7/26 14:02, Claudio Fontana wrote:
> Hello,
> 
> On 4/5/26 17:26, Trieu Huynh wrote:
>> From: Trieu Huynh <vikingtc4@gmail.com>
>>
>> Add start_time, total_time, received_normal_pages,
>> received_zero_pages, and received_xbzrle_pages to
>> MigrationIncomingState.
>>
>> start_time is recorded when the incoming state transitions to ACTIVE;
>> total_time is recorded when it transitions to COMPLETED. The page
>> counters are incremented in ram_load_precopy() as each page type is
>> received from the source.
>>
>> These fields will be used by a subsequent patch to populate
>> fill_destination_migration_info() for the migration COMPLETED case.
>>
>> Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
>> ---
>>  migration/migration.c |  2 ++
>>  migration/migration.h | 17 +++++++++++++++++
>>  migration/ram.c       |  3 +++
>>  3 files changed, 22 insertions(+)
>>
>> diff --git a/migration/migration.c b/migration/migration.c
>> index 5c9aaa6e58..17c9a8b344 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -726,6 +726,7 @@ static void process_incoming_migration_bh(void *opaque)
>>       */
>>      migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
>>                        MIGRATION_STATUS_COMPLETED);
>> +    mis->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - mis->start_time;
>>      migration_incoming_state_destroy();
>>  }
>>  
>> @@ -758,6 +759,7 @@ process_incoming_migration_co(void *opaque)
>>      migrate_set_state(&mis->state, MIGRATION_STATUS_SETUP,
>>                        MIGRATION_STATUS_ACTIVE);
>>  
>> +    mis->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
>>      mis->loadvm_co = qemu_coroutine_self();
>>      ret = qemu_loadvm_state(mis->from_src_file, &local_err);
>>      mis->loadvm_co = NULL;
>> diff --git a/migration/migration.h b/migration/migration.h
>> index b6888daced..cd51ae452c 100644
>> --- a/migration/migration.h
>> +++ b/migration/migration.h
>> @@ -176,6 +176,23 @@ struct MigrationIncomingState {
>>      /* PostCopyFD's for external userfaultfds & handlers of shared memory */
>>      GArray   *postcopy_remote_fds;
>>  
>> +    /*
>> +     * Timestamps for reporting migration duration via query-migrate on the
>> +     * destination. start_time is recorded when the state moves to ACTIVE;
>> +     * total_time is recorded when it moves to COMPLETED.
>> +     */
>> +    int64_t start_time;
>> +    int64_t total_time;
> 
> nit: since this is a timestamp and these are directly linked to state changes,
> why not call these:
> 
> int64_t migration_active_ts;
> int64_t migration_completed_ts;

I got the second one wrong, it is not a timestamp, that is indeed a time.
So clarity in the name seems to be more than a nit. What about:

int64_t migration_active_ts;      /* ms */
int64_t migration_completed_time; /* ms */

Thanks,

Claudio

> 
>> +
>> +    /*
>> +     * Page counters for reporting RAM statistics via query-migrate on the
>> +     * destination.  Incremented in ram_load_precopy() as each page type
>> +     * is received.
>> +     */
>> +    uint64_t received_normal_pages;
>> +    uint64_t received_zero_pages;
>> +    uint64_t received_xbzrle_pages;
>> +
>>      MigrationStatus state;
>>  
>>      /*
>> diff --git a/migration/ram.c b/migration/ram.c
>> index 979751f61b..6646e5daad 100644
>> --- a/migration/ram.c
>> +++ b/migration/ram.c
>> @@ -4417,10 +4417,12 @@ static int ram_load_precopy(QEMUFile *f)
>>                  break;
>>              }
>>              ram_handle_zero(host, TARGET_PAGE_SIZE);
>> +            mis->received_zero_pages++;
>>              break;
>>  
>>          case RAM_SAVE_FLAG_PAGE:
>>              qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
>> +            mis->received_normal_pages++;
>>              break;
>>  
>>          case RAM_SAVE_FLAG_XBZRLE:
>> @@ -4430,6 +4432,7 @@ static int ram_load_precopy(QEMUFile *f)
>>                  ret = -EINVAL;
>>                  break;
>>              }
>> +            mis->received_xbzrle_pages++;
>>              break;
>>          case RAM_SAVE_FLAG_MULTIFD_FLUSH:
>>              multifd_recv_sync_main();
>
Re: [PATCH 1/2] migration: track timing and received pages in MigrationIncomingState
Posted by Trieu Huynh 4 days ago
On Tue, Apr 07, 2026 at 02:11:54PM +0200, Claudio Fontana wrote:
> On 4/7/26 14:02, Claudio Fontana wrote:
> > Hello,
> > 
> > On 4/5/26 17:26, Trieu Huynh wrote:
> >> From: Trieu Huynh <vikingtc4@gmail.com>
> >>
> >> Add start_time, total_time, received_normal_pages,
> >> received_zero_pages, and received_xbzrle_pages to
> >> MigrationIncomingState.
> >>
> >> start_time is recorded when the incoming state transitions to ACTIVE;
> >> total_time is recorded when it transitions to COMPLETED. The page
> >> counters are incremented in ram_load_precopy() as each page type is
> >> received from the source.
> >>
> >> These fields will be used by a subsequent patch to populate
> >> fill_destination_migration_info() for the migration COMPLETED case.
> >>
> >> Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
> >> ---
> >>  migration/migration.c |  2 ++
> >>  migration/migration.h | 17 +++++++++++++++++
> >>  migration/ram.c       |  3 +++
> >>  3 files changed, 22 insertions(+)
> >>
> >> diff --git a/migration/migration.c b/migration/migration.c
> >> index 5c9aaa6e58..17c9a8b344 100644
> >> --- a/migration/migration.c
> >> +++ b/migration/migration.c
> >> @@ -726,6 +726,7 @@ static void process_incoming_migration_bh(void *opaque)
> >>       */
> >>      migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
> >>                        MIGRATION_STATUS_COMPLETED);
> >> +    mis->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - mis->start_time;
> >>      migration_incoming_state_destroy();
> >>  }
> >>  
> >> @@ -758,6 +759,7 @@ process_incoming_migration_co(void *opaque)
> >>      migrate_set_state(&mis->state, MIGRATION_STATUS_SETUP,
> >>                        MIGRATION_STATUS_ACTIVE);
> >>  
> >> +    mis->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
> >>      mis->loadvm_co = qemu_coroutine_self();
> >>      ret = qemu_loadvm_state(mis->from_src_file, &local_err);
> >>      mis->loadvm_co = NULL;
> >> diff --git a/migration/migration.h b/migration/migration.h
> >> index b6888daced..cd51ae452c 100644
> >> --- a/migration/migration.h
> >> +++ b/migration/migration.h
> >> @@ -176,6 +176,23 @@ struct MigrationIncomingState {
> >>      /* PostCopyFD's for external userfaultfds & handlers of shared memory */
> >>      GArray   *postcopy_remote_fds;
> >>  
> >> +    /*
> >> +     * Timestamps for reporting migration duration via query-migrate on the
> >> +     * destination. start_time is recorded when the state moves to ACTIVE;
> >> +     * total_time is recorded when it moves to COMPLETED.
> >> +     */
> >> +    int64_t start_time;
> >> +    int64_t total_time;
> > 
> > nit: since this is a timestamp and these are directly linked to state changes,
> > why not call these:
> > 
> > int64_t migration_active_ts;
> > int64_t migration_completed_ts;
> 
> I got the second one wrong, it is not a timestamp, that is indeed a time.
> So clarity in the name seems to be more than a nit. What about:
> 
> int64_t migration_active_ts;      /* ms */
> int64_t migration_completed_time; /* ms */
> 
make sense to me. will update in v2. thank you.
> Thanks,
> 
> Claudio
> 
> > 
> >> +
> >> +    /*
> >> +     * Page counters for reporting RAM statistics via query-migrate on the
> >> +     * destination.  Incremented in ram_load_precopy() as each page type
> >> +     * is received.
> >> +     */
> >> +    uint64_t received_normal_pages;
> >> +    uint64_t received_zero_pages;
> >> +    uint64_t received_xbzrle_pages;
> >> +
> >>      MigrationStatus state;
> >>  
> >>      /*
> >> diff --git a/migration/ram.c b/migration/ram.c
> >> index 979751f61b..6646e5daad 100644
> >> --- a/migration/ram.c
> >> +++ b/migration/ram.c
> >> @@ -4417,10 +4417,12 @@ static int ram_load_precopy(QEMUFile *f)
> >>                  break;
> >>              }
> >>              ram_handle_zero(host, TARGET_PAGE_SIZE);
> >> +            mis->received_zero_pages++;
> >>              break;
> >>  
> >>          case RAM_SAVE_FLAG_PAGE:
> >>              qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
> >> +            mis->received_normal_pages++;
> >>              break;
> >>  
> >>          case RAM_SAVE_FLAG_XBZRLE:
> >> @@ -4430,6 +4432,7 @@ static int ram_load_precopy(QEMUFile *f)
> >>                  ret = -EINVAL;
> >>                  break;
> >>              }
> >> +            mis->received_xbzrle_pages++;
> >>              break;
> >>          case RAM_SAVE_FLAG_MULTIFD_FLUSH:
> >>              multifd_recv_sync_main();
> > 
> 
BRs,
Trieu Huynh