Skip to content
Snippets Groups Projects
  1. Aug 02, 2022
  2. Jul 20, 2022
    • Leonardo Bras's avatar
      migration: Avoid false-positive on non-supported scenarios for zero-copy-send · 90eb69e4
      Leonardo Bras authored
      
      Migration with zero-copy-send currently has it's limitations, as it can't
      be used with TLS nor any kind of compression. In such scenarios, it should
      output errors during parameter / capability setting.
      
      But currently there are some ways of setting this not-supported scenarios
      without printing the error message:
      
      !) For 'compression' capability, it works by enabling it together with
      zero-copy-send. This happens because the validity test for zero-copy uses
      the helper unction migrate_use_compression(), which check for compression
      presence in s->enabled_capabilities[MIGRATION_CAPABILITY_COMPRESS].
      
      The point here is: the validity test happens before the capability gets
      enabled. If all of them get enabled together, this test will not return
      error.
      
      In order to fix that, replace migrate_use_compression() by directly testing
      the cap_list parameter migrate_caps_check().
      
      2) For features enabled by parameters such as TLS & 'multifd_compression',
      there was also a possibility of setting non-supported scenarios: setting
      zero-copy-send first, then setting the unsupported parameter.
      
      In order to fix that, also add a check for parameters conflicting with
      zero-copy-send on migrate_params_check().
      
      3) XBZRLE is also a compression capability, so it makes sense to also add
      it to the list of capabilities which are not supported with zero-copy-send.
      
      Fixes: 1abaec9a ("migration: Change zero_copy_send from migration parameter to migration capability")
      Signed-off-by: default avatarLeonardo Bras <leobras@redhat.com>
      Message-Id: <20220719122345.253713-1-leobras@redhat.com>
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      90eb69e4
    • Juan Quintela's avatar
      multifd: Document the locking of MultiFD{Send/Recv}Params · 4a8f19c9
      Juan Quintela authored
      
      Reorder the structures so we can know if the fields are:
      - Read only
      - Their own locking (i.e. sems)
      - Protected by 'mutex'
      - Only for the multifd channel
      
      Signed-off-by: default avatarJuan Quintela <quintela@redhat.com>
      Message-Id: <20220531104318.7494-2-quintela@redhat.com>
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
        dgilbert: Typo fixes from Chen Zhang
      4a8f19c9
    • Leonardo Bras's avatar
      migration/multifd: Report to user when zerocopy not working · d59c40cc
      Leonardo Bras authored
      
      Some errors, like the lack of Scatter-Gather support by the network
      interface(NETIF_F_SG) may cause sendmsg(...,MSG_ZEROCOPY) to fail on using
      zero-copy, which causes it to fall back to the default copying mechanism.
      
      After each full dirty-bitmap scan there should be a zero-copy flush
      happening, which checks for errors each of the previous calls to
      sendmsg(...,MSG_ZEROCOPY). If all of them failed to use zero-copy, then
      increment dirty_sync_missed_zero_copy migration stat to let the user know
      about it.
      
      Signed-off-by: default avatarLeonardo Bras <leobras@redhat.com>
      Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Acked-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220711211112.18951-4-leobras@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      d59c40cc
    • Leonardo Bras's avatar
      Add dirty-sync-missed-zero-copy migration stat · cf20c897
      Leonardo Bras authored
      
      Signed-off-by: default avatarLeonardo Bras <leobras@redhat.com>
      Acked-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Acked-by: default avatarPeter Xu <peterx@redhat.com>
      Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Message-Id: <20220711211112.18951-3-leobras@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      cf20c897
    • Daniel P. Berrangé's avatar
      migration: remove unreachable code after reading data · 5f87072e
      Daniel P. Berrangé authored
      
      The code calls qio_channel_read() in a loop when it reports
      QIO_CHANNEL_ERR_BLOCK. This code is reported when errno==EAGAIN.
      
      As such the later block of code will always hit the 'errno != EAGAIN'
      condition, making the final 'else' unreachable.
      
      Fixes: Coverity CID 1490203
      Signed-off-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Message-Id: <20220627135318.156121-1-berrange@redhat.com>
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      5f87072e
    • Peter Xu's avatar
      migration: Respect postcopy request order in preemption mode · 82b54ef4
      Peter Xu authored
      
      With preemption mode on, when we see a postcopy request that was requesting
      for exactly the page that we have preempted before (so we've partially sent
      the page already via PRECOPY channel and it got preempted by another
      postcopy request), currently we drop the request so that after all the
      other postcopy requests are serviced then we'll go back to precopy stream
      and start to handle that.
      
      We dropped the request because we can't send it via postcopy channel since
      the precopy channel already contains partial of the data, and we can only
      send a huge page via one channel as a whole.  We can't split a huge page
      into two channels.
      
      That's a very corner case and that works, but there's a change on the order
      of postcopy requests that we handle since we're postponing this (unlucky)
      postcopy request to be later than the other queued postcopy requests.  The
      problem is there's a possibility that when the guest was very busy, the
      postcopy queue can be always non-empty, it means this dropped request will
      never be handled until the end of postcopy migration. So, there's a chance
      that there's one dest QEMU vcpu thread waiting for a page fault for an
      extremely long time just because it's unluckily accessing the specific page
      that was preempted before.
      
      The worst case time it needs can be as long as the whole postcopy migration
      procedure.  It's extremely unlikely to happen, but when it happens it's not
      good.
      
      The root cause of this problem is because we treat pss->postcopy_requested
      variable as with two meanings bound together, as the variable shows:
      
        1. Whether this page request is urgent, and,
        2. Which channel we should use for this page request.
      
      With the old code, when we set postcopy_requested it means either both (1)
      and (2) are true, or both (1) and (2) are false.  We can never have (1)
      and (2) to have different values.
      
      However it doesn't necessarily need to be like that.  It's very legal that
      there's one request that has (1) very high urgency, but (2) we'd like to
      use the precopy channel.  Just like the corner case we were discussing
      above.
      
      To differenciate the two meanings better, introduce a new field called
      postcopy_target_channel, showing which channel we should use for this page
      request, so as to cover the old meaning (2) only.  Then we leave the
      postcopy_requested variable to stand only for meaning (1), which is the
      urgency of this page request.
      
      With this change, we can easily boost priority of a preempted precopy page
      as long as we know that page is also requested as a postcopy page.  So with
      the new approach in get_queued_page() instead of dropping that request, we
      send it right away with the precopy channel so we get back the ordering of
      the page faults just like how they're requested on dest.
      
      Reported-by: default avatarManish Mishra <manish.mishra@nutanix.com>
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Reviewed-by: default avatarManish Mishra <manish.mishra@nutanix.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185520.27583-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      82b54ef4
    • Peter Xu's avatar
      migration: Enable TLS for preempt channel · f0afaf6c
      Peter Xu authored
      
      This patch is based on the async preempt channel creation.  It continues
      wiring up the new channel with TLS handshake to destionation when enabled.
      
      Note that only the src QEMU needs such operation; the dest QEMU does not
      need any change for TLS support due to the fact that all channels are
      established synchronously there, so all the TLS magic is already properly
      handled by migration_tls_channel_process_incoming().
      
      Reviewed-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185518.27529-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      f0afaf6c
    • Peter Xu's avatar
      migration: Export tls-[creds|hostname|authz] params to cmdline too · 9a266627
      Peter Xu authored
      
      It's useful for specifying tls credentials all in the cmdline (along with
      the -object tls-creds-*), especially for debugging purpose.
      
      The trick here is we must remember to not free these fields again in the
      finalize() function of migration object, otherwise it'll cause double-free.
      
      The thing is when destroying an object, we'll first destroy the properties
      that bound to the object, then the object itself.  To be explicit, when
      destroy the object in object_finalize() we have such sequence of
      operations:
      
          object_property_del_all(obj);
          object_deinit(obj, ti);
      
      So after this change the two fields are properly released already even
      before reaching the finalize() function but in object_property_del_all(),
      hence we don't need to free them anymore in finalize() or it's double-free.
      
      This also fixes a trivial memory leak for tls-authz as we forgot to free it
      before this patch.
      
      Reviewed-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185515.27475-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      9a266627
    • Peter Xu's avatar
      migration: Add helpers to detect TLS capability · 85a8578e
      Peter Xu authored
      
      Add migrate_channel_requires_tls() to detect whether the specific channel
      requires TLS, leveraging the recently introduced migrate_use_tls().  No
      functional change intended.
      
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185513.27421-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      85a8578e
    • Peter Xu's avatar
      migration: Add property x-postcopy-preempt-break-huge · c8750de1
      Peter Xu authored
      
      Add a property field that can conditionally disable the "break sending huge
      page" behavior in postcopy preemption.  By default it's enabled.
      
      It should only be used for debugging purposes, and we should never remove
      the "x-" prefix.
      
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Reviewed-by: default avatarManish Mishra <manish.mishra@nutanix.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185511.27366-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      c8750de1
    • Peter Xu's avatar
      migration: Create the postcopy preempt channel asynchronously · d0edb8a1
      Peter Xu authored
      
      This patch allows the postcopy preempt channel to be created
      asynchronously.  The benefit is that when the connection is slow, we won't
      take the BQL (and potentially block all things like QMP) for a long time
      without releasing.
      
      A function postcopy_preempt_wait_channel() is introduced, allowing the
      migration thread to be able to wait on the channel creation.  The channel
      is always created by the main thread, in which we'll kick a new semaphore
      to tell the migration thread that the channel has created.
      
      We'll need to wait for the new channel in two places: (1) when there's a
      new postcopy migration that is starting, or (2) when there's a postcopy
      migration to resume.
      
      For the start of migration, we don't need to wait for this channel until
      when we want to start postcopy, aka, postcopy_start().  We'll fail the
      migration if we found that the channel creation failed (which should
      probably not happen at all in 99% of the cases, because the main channel is
      using the same network topology).
      
      For a postcopy recovery, we'll need to wait in postcopy_pause().  In that
      case if the channel creation failed, we can't fail the migration or we'll
      crash the VM, instead we keep in PAUSED state, waiting for yet another
      recovery.
      
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Reviewed-by: default avatarManish Mishra <manish.mishra@nutanix.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185509.27311-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      d0edb8a1
    • Peter Xu's avatar
      migration: Postcopy recover with preempt enabled · 60bb3c58
      Peter Xu authored
      
      To allow postcopy recovery, the ram fast load (preempt-only) dest QEMU thread
      needs similar handling on fault tolerance.  When ram_load_postcopy() fails,
      instead of stopping the thread it halts with a semaphore, preparing to be
      kicked again when recovery is detected.
      
      A mutex is introduced to make sure there's no concurrent operation upon the
      socket.  To make it simple, the fast ram load thread will take the mutex during
      its whole procedure, and only release it if it's paused.  The fast-path socket
      will be properly released by the main loading thread safely when there's
      network failures during postcopy with that mutex held.
      
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185506.27257-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      60bb3c58
    • Peter Xu's avatar
      migration: Postcopy preemption enablement · c01b16ed
      Peter Xu authored
      
      This patch enables postcopy-preempt feature.
      
      It contains two major changes to the migration logic:
      
      (1) Postcopy requests are now sent via a different socket from precopy
          background migration stream, so as to be isolated from very high page
          request delays.
      
      (2) For huge page enabled hosts: when there's postcopy requests, they can now
          intercept a partial sending of huge host pages on src QEMU.
      
      After this patch, we'll live migrate a VM with two channels for postcopy: (1)
      PRECOPY channel, which is the default channel that transfers background pages;
      and (2) POSTCOPY channel, which only transfers requested pages.
      
      There's no strict rule of which channel to use, e.g., if a requested page is
      already being transferred on precopy channel, then we will keep using the same
      precopy channel to transfer the page even if it's explicitly requested.  In 99%
      of the cases we'll prioritize the channels so we send requested page via the
      postcopy channel as long as possible.
      
      On the source QEMU, when we found a postcopy request, we'll interrupt the
      PRECOPY channel sending process and quickly switch to the POSTCOPY channel.
      After we serviced all the high priority postcopy pages, we'll switch back to
      PRECOPY channel so that we'll continue to send the interrupted huge page again.
      There's no new thread introduced on src QEMU.
      
      On the destination QEMU, one new thread is introduced to receive page data from
      the postcopy specific socket (done in the preparation patch).
      
      This patch has a side effect: after sending postcopy pages, previously we'll
      assume the guest will access follow up pages so we'll keep sending from there.
      Now it's changed.  Instead of going on with a postcopy requested page, we'll go
      back and continue sending the precopy huge page (which can be intercepted by a
      postcopy request so the huge page can be sent partially before).
      
      Whether that's a problem is debatable, because "assuming the guest will
      continue to access the next page" may not really suite when huge pages are
      used, especially if the huge page is large (e.g. 1GB pages).  So that locality
      hint is much meaningless if huge pages are used.
      
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185504.27203-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      c01b16ed
    • Peter Xu's avatar
      migration: Postcopy preemption preparation on channel creation · 36f62f11
      Peter Xu authored
      
      Create a new socket for postcopy to be prepared to send postcopy requested
      pages via this specific channel, so as to not get blocked by precopy pages.
      
      A new thread is also created on dest qemu to receive data from this new channel
      based on the ram_load_postcopy() routine.
      
      The ram_load_postcopy(POSTCOPY) branch and the thread has not started to
      function, and that'll be done in follow up patches.
      
      Cleanup the new sockets on both src/dst QEMUs, meanwhile look after the new
      thread too to make sure it'll be recycled properly.
      
      Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Reviewed-by: default avatarJuan Quintela <quintela@redhat.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185502.27149-1-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
        dgilbert: With Peter's fix to quieten compiler warning on
             start_migration
      36f62f11
    • Peter Xu's avatar
      migration: Add postcopy-preempt capability · ce5b0f4a
      Peter Xu authored
      
      Firstly, postcopy already preempts precopy due to the fact that we do
      unqueue_page() first before looking into dirty bits.
      
      However that's not enough, e.g., when there're host huge page enabled, when
      sending a precopy huge page, a postcopy request needs to wait until the whole
      huge page that is sending to finish.  That could introduce quite some delay,
      the bigger the huge page is the larger delay it'll bring.
      
      This patch adds a new capability to allow postcopy requests to preempt existing
      precopy page during sending a huge page, so that postcopy requests can be
      serviced even faster.
      
      Meanwhile to send it even faster, bypass the precopy stream by providing a
      standalone postcopy socket for sending requested pages.
      
      Since the new behavior will not be compatible with the old behavior, this will
      not be the default, it's enabled only when the new capability is set on both
      src/dst QEMUs.
      
      This patch only adds the capability itself, the logic will be added in follow
      up patches.
      
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Reviewed-by: default avatarJuan Quintela <quintela@redhat.com>
      Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <20220707185342.26794-2-peterx@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      ce5b0f4a
    • Ilya Leoshkevich's avatar
      multifd: Copy pages before compressing them with zlib · 007e179e
      Ilya Leoshkevich authored
      zlib_send_prepare() compresses pages of a running VM. zlib does not
      make any thread-safety guarantees with respect to changing deflate()
      input concurrently with deflate() [1].
      
      One can observe problems due to this with the IBM zEnterprise Data
      Compression accelerator capable zlib [2]. When the hardware
      acceleration is enabled, migration/multifd/tcp/plain/zlib test fails
      intermittently [3] due to sliding window corruption. The accelerator's
      architecture explicitly discourages concurrent accesses [4]:
      
          Page 26-57, "Other Conditions":
      
          As observed by this CPU, other CPUs, and channel
          programs, references to the parameter block, first,
          second, and third operands may be multiple-access
          references, accesses to these storage locations are
          not necessarily block-concurrent, and the sequence
          of these accesses or references is undefined.
      
      Mark Adler pointed out that vanilla zlib performs double fetches under
      certain circumstances as well [5], therefore we need to copy data
      before passing it to deflate().
      
      [1] https://zlib.net/manual.html
      [2] https://github.com/madler/zlib/pull/410
      [3] https://lists.nongnu.org/archive/html/qemu-devel/2022-03/msg03988.html
      [4] http://publibfp.dhe.ibm.com/epubs/pdf/a227832c.pdf
      [5] https://lists.gnu.org/archive/html/qemu-devel/2022-07/msg00889.html
      
      
      
      Signed-off-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
      Message-Id: <20220705203559.2960949-1-iii@linux.ibm.com>
      Reviewed-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      007e179e
    • Hyman Huang's avatar
      migration/dirtyrate: Refactor dirty page rate calculation · 8244166d
      Hyman Huang authored
      
      abstract out dirty log change logic into function
      global_dirty_log_change.
      
      abstract out dirty page rate calculation logic via
      dirty-ring into function vcpu_calculate_dirtyrate.
      
      abstract out mathematical dirty page rate calculation
      into do_calculate_dirtyrate, decouple it from DirtyStat.
      
      rename set_sample_page_period to dirty_stat_wait, which
      is well-understood and will be reused in dirtylimit.
      
      handle cpu hotplug/unplug scenario during measurement of
      dirty page rate.
      
      export util functions outside migration.
      
      Signed-off-by: default avatarHyman Huang(黄勇) <huangy81@chinatelecom.cn>
      Reviewed-by: default avatarPeter Xu <peterx@redhat.com>
      Message-Id: <7b6f6f4748d5b3d017b31a0429e630229ae97538.1656177590.git.huangy81@chinatelecom.cn>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      8244166d
  3. Jul 12, 2022
  4. Jun 23, 2022
  5. Jun 22, 2022
Loading