diff mbox series

[RFC,10/15] migration: Move static var in ram_block_from_stream() into global

Message ID 20220119080929.39485-11-peterx@redhat.com
State New
Headers show
Series migration: Postcopy Preemption | expand

Commit Message

Peter Xu Jan. 19, 2022, 8:09 a.m. UTC
Static variable is very unfriendly to threading of ram_block_from_stream().
Move it into MigrationIncomingState.

Make the incoming state pointer to be passed over to ram_block_from_stream() on
both caller sites.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 migration/migration.h |  3 ++-
 migration/ram.c       | 13 +++++++++----
 2 files changed, 11 insertions(+), 5 deletions(-)

Comments

Dr. David Alan Gilbert Feb. 3, 2022, 5:48 p.m. UTC | #1
* Peter Xu (peterx@redhat.com) wrote:
> Static variable is very unfriendly to threading of ram_block_from_stream().
> Move it into MigrationIncomingState.
> 
> Make the incoming state pointer to be passed over to ram_block_from_stream() on
> both caller sites.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>

OK, but I'm not sure if I noticed where you changed this to be per
channel later?



Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

Dave
> ---
>  migration/migration.h |  3 ++-
>  migration/ram.c       | 13 +++++++++----
>  2 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/migration/migration.h b/migration/migration.h
> index 35e7f7babe..34b79cb961 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -66,7 +66,8 @@ typedef struct {
>  /* State for the incoming migration */
>  struct MigrationIncomingState {
>      QEMUFile *from_src_file;
> -
> +    /* Previously received RAM's RAMBlock pointer */
> +    RAMBlock *last_recv_block;
>      /* A hook to allow cleanup at the end of incoming migration */
>      void *transport_data;
>      void (*transport_cleanup)(void *data);
> diff --git a/migration/ram.c b/migration/ram.c
> index 3f823ffffc..3a7d943f9c 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -3183,12 +3183,14 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
>   *
>   * Returns a pointer from within the RCU-protected ram_list.
>   *
> + * @mis: the migration incoming state pointer
>   * @f: QEMUFile where to read the data from
>   * @flags: Page flags (mostly to see if it's a continuation of previous block)
>   */
> -static inline RAMBlock *ram_block_from_stream(QEMUFile *f, int flags)
> +static inline RAMBlock *ram_block_from_stream(MigrationIncomingState *mis,
> +                                              QEMUFile *f, int flags)
>  {
> -    static RAMBlock *block;
> +    RAMBlock *block = mis->last_recv_block;
>      char id[256];
>      uint8_t len;
>  
> @@ -3215,6 +3217,8 @@ static inline RAMBlock *ram_block_from_stream(QEMUFile *f, int flags)
>          return NULL;
>      }
>  
> +    mis->last_recv_block = block;
> +
>      return block;
>  }
>  
> @@ -3667,7 +3671,7 @@ static int ram_load_postcopy(QEMUFile *f)
>          trace_ram_load_postcopy_loop((uint64_t)addr, flags);
>          if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
>                       RAM_SAVE_FLAG_COMPRESS_PAGE)) {
> -            block = ram_block_from_stream(f, flags);
> +            block = ram_block_from_stream(mis, f, flags);
>              if (!block) {
>                  ret = -EINVAL;
>                  break;
> @@ -3881,6 +3885,7 @@ void colo_flush_ram_cache(void)
>   */
>  static int ram_load_precopy(QEMUFile *f)
>  {
> +    MigrationIncomingState *mis = migration_incoming_get_current();
>      int flags = 0, ret = 0, invalid_flags = 0, len = 0, i = 0;
>      /* ADVISE is earlier, it shows the source has the postcopy capability on */
>      bool postcopy_advised = postcopy_is_advised();
> @@ -3919,7 +3924,7 @@ static int ram_load_precopy(QEMUFile *f)
>  
>          if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
>                       RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
> -            RAMBlock *block = ram_block_from_stream(f, flags);
> +            RAMBlock *block = ram_block_from_stream(mis, f, flags);
>  
>              host = host_from_ram_block_offset(block, addr);
>              /*
> -- 
> 2.32.0
>
Peter Xu Feb. 8, 2022, 3:51 a.m. UTC | #2
On Thu, Feb 03, 2022 at 05:48:31PM +0000, Dr. David Alan Gilbert wrote:
> * Peter Xu (peterx@redhat.com) wrote:
> > Static variable is very unfriendly to threading of ram_block_from_stream().
> > Move it into MigrationIncomingState.
> > 
> > Make the incoming state pointer to be passed over to ram_block_from_stream() on
> > both caller sites.
> > 
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> 
> OK, but I'm not sure if I noticed where you changed this to be per
> channel later?

It's done in the last patch where it'll start to pass over "channel" index into
ram_block_from_stream():

static inline RAMBlock *ram_block_from_stream(MigrationIncomingState *mis,
                                              QEMUFile *f, int flags,
                                              int channel)
{
    RAMBlock *block = mis->last_recv_block[channel];
    ...
}

I could have moved it into the new PostcopyTmpPage structure, but it'll be a
bit weird because precopy also uses this to cache the block info, hence I made
it an array.

> 
> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

Thanks,
diff mbox series

Patch

diff --git a/migration/migration.h b/migration/migration.h
index 35e7f7babe..34b79cb961 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -66,7 +66,8 @@  typedef struct {
 /* State for the incoming migration */
 struct MigrationIncomingState {
     QEMUFile *from_src_file;
-
+    /* Previously received RAM's RAMBlock pointer */
+    RAMBlock *last_recv_block;
     /* A hook to allow cleanup at the end of incoming migration */
     void *transport_data;
     void (*transport_cleanup)(void *data);
diff --git a/migration/ram.c b/migration/ram.c
index 3f823ffffc..3a7d943f9c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3183,12 +3183,14 @@  static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
  *
  * Returns a pointer from within the RCU-protected ram_list.
  *
+ * @mis: the migration incoming state pointer
  * @f: QEMUFile where to read the data from
  * @flags: Page flags (mostly to see if it's a continuation of previous block)
  */
-static inline RAMBlock *ram_block_from_stream(QEMUFile *f, int flags)
+static inline RAMBlock *ram_block_from_stream(MigrationIncomingState *mis,
+                                              QEMUFile *f, int flags)
 {
-    static RAMBlock *block;
+    RAMBlock *block = mis->last_recv_block;
     char id[256];
     uint8_t len;
 
@@ -3215,6 +3217,8 @@  static inline RAMBlock *ram_block_from_stream(QEMUFile *f, int flags)
         return NULL;
     }
 
+    mis->last_recv_block = block;
+
     return block;
 }
 
@@ -3667,7 +3671,7 @@  static int ram_load_postcopy(QEMUFile *f)
         trace_ram_load_postcopy_loop((uint64_t)addr, flags);
         if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
                      RAM_SAVE_FLAG_COMPRESS_PAGE)) {
-            block = ram_block_from_stream(f, flags);
+            block = ram_block_from_stream(mis, f, flags);
             if (!block) {
                 ret = -EINVAL;
                 break;
@@ -3881,6 +3885,7 @@  void colo_flush_ram_cache(void)
  */
 static int ram_load_precopy(QEMUFile *f)
 {
+    MigrationIncomingState *mis = migration_incoming_get_current();
     int flags = 0, ret = 0, invalid_flags = 0, len = 0, i = 0;
     /* ADVISE is earlier, it shows the source has the postcopy capability on */
     bool postcopy_advised = postcopy_is_advised();
@@ -3919,7 +3924,7 @@  static int ram_load_precopy(QEMUFile *f)
 
         if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
                      RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
-            RAMBlock *block = ram_block_from_stream(f, flags);
+            RAMBlock *block = ram_block_from_stream(mis, f, flags);
 
             host = host_from_ram_block_offset(block, addr);
             /*