From: Markus Armbruster <armbru@redhat.com>
To: Fabiano Rosas <farosas@suse.de>
Cc: qemu-devel@nongnu.org,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Peter Xu" <peterx@redhat.com>,
devel@lists.libvirt.org, "Eduardo Habkost" <eduardo@habkost.net>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Yanan Wang" <wangyanan55@huawei.com>,
"Eric Blake" <eblake@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Laurent Vivier" <lvivier@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>
Subject: Re: [PATCH 5/6] migration: Remove non-multifd compression
Date: Fri, 26 Apr 2024 16:27:20 +0200 [thread overview]
Message-ID: <87zftgqjw7.fsf@pond.sub.org> (raw)
In-Reply-To: <20240425150939.19268-6-farosas@suse.de> (Fabiano Rosas's message of "Thu, 25 Apr 2024 12:09:38 -0300")
Fabiano Rosas <farosas@suse.de> writes:
> The 'compress' migration capability enables the old compression code
> which has shown issues over the years and is thought to be less stable
> and tested than the more recent multifd-based compression. The old
> compression code has been deprecated in 8.2 and now is time to remove
> it.
>
> Deprecation commit 864128df46 ("migration: Deprecate old compression
> method").
>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
[...]
> diff --git a/migration/options.c b/migration/options.c
> index 5049bfb78e..5b0658bad1 100644
> --- a/migration/options.c
> +++ b/migration/options.c
> @@ -40,13 +40,6 @@
> * for sending the last part */
> #define DEFAULT_MIGRATE_SET_DOWNTIME 300
>
> -/* Default compression thread count */
> -#define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
> -/* Default decompression thread count, usually decompression is at
> - * least 4 times as fast as compression.*/
> -#define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2
> -/*0: means nocompress, 1: best speed, ... 9: best compress ratio */
> -#define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
> /* Define default autoconverge cpu throttle migration parameters */
> #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
> #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
> @@ -92,8 +85,6 @@ Property migration_properties[] = {
> send_configuration, true),
> DEFINE_PROP_BOOL("send-section-footer", MigrationState,
> send_section_footer, true),
> - DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
> - decompress_error_check, true),
> DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
> multifd_flush_after_each_section, false),
> DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
> @@ -102,17 +93,6 @@ Property migration_properties[] = {
> preempt_pre_7_2, false),
>
> /* Migration parameters */
> - DEFINE_PROP_UINT8("x-compress-level", MigrationState,
> - parameters.compress_level,
> - DEFAULT_MIGRATE_COMPRESS_LEVEL),
> - DEFINE_PROP_UINT8("x-compress-threads", MigrationState,
> - parameters.compress_threads,
> - DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT),
> - DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState,
> - parameters.compress_wait_thread, true),
> - DEFINE_PROP_UINT8("x-decompress-threads", MigrationState,
> - parameters.decompress_threads,
> - DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT),
> DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
> parameters.throttle_trigger_threshold,
> DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
> @@ -188,7 +168,6 @@ Property migration_properties[] = {
> DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
> DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
> DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
> - DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS),
> DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
> DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
> DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
> @@ -231,13 +210,6 @@ bool migrate_colo(void)
> return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
> }
>
> -bool migrate_compress(void)
> -{
> - MigrationState *s = migrate_get_current();
> -
> - return s->capabilities[MIGRATION_CAPABILITY_COMPRESS];
> -}
> -
Please also drop the declaration from migration/options.h.
> bool migrate_dirty_bitmaps(void)
> {
> MigrationState *s = migrate_get_current();
> @@ -451,7 +423,6 @@ INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
> MIGRATION_CAPABILITY_AUTO_CONVERGE,
> MIGRATION_CAPABILITY_RELEASE_RAM,
> MIGRATION_CAPABILITY_RDMA_PIN_ALL,
> - MIGRATION_CAPABILITY_COMPRESS,
> MIGRATION_CAPABILITY_XBZRLE,
> MIGRATION_CAPABILITY_X_COLO,
> MIGRATION_CAPABILITY_VALIDATE_UUID,
> @@ -476,11 +447,6 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
> ERRP_GUARD();
> MigrationIncomingState *mis = migration_incoming_get_current();
>
> - if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
> - warn_report("old compression method is deprecated;"
> - " use multifd compression methods instead");
> - }
> -
> #ifndef CONFIG_REPLICATION
> if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
> error_setg(errp, "QEMU compiled without replication module"
> @@ -549,7 +515,6 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
> #ifdef CONFIG_LINUX
> if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
> (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
> - new_caps[MIGRATION_CAPABILITY_COMPRESS] ||
> new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
> migrate_multifd_compression() ||
> migrate_tls())) {
> @@ -571,17 +536,6 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
> return false;
> }
>
> - /*
> - * Preempt mode requires urgent pages to be sent in separate
> - * channel, OTOH compression logic will disorder all pages into
> - * different compression channels, which is not compatible with the
> - * preempt assumptions on channel assignments.
> - */
> - if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
> - error_setg(errp, "Postcopy preempt not compatible with compress");
> - return false;
> - }
> -
> if (migrate_incoming_started()) {
> error_setg(errp,
> "Postcopy preempt must be set before incoming starts");
> @@ -590,10 +544,6 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
> }
>
> if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
> - if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
> - error_setg(errp, "Multifd is not compatible with compress");
> - return false;
> - }
> if (migrate_incoming_started()) {
> error_setg(errp, "Multifd must be set before incoming starts");
> return false;
> @@ -628,13 +578,6 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
> }
> }
>
> - if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
> - if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
> - error_setg(errp, "Compression is not compatible with xbzrle");
> - return false;
> - }
> - }
> -
> if (new_caps[MIGRATION_CAPABILITY_MAPPED_RAM]) {
> if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
> error_setg(errp,
> @@ -642,12 +585,6 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
> return false;
> }
>
> - if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
> - error_setg(errp,
> - "Mapped-ram migration is incompatible with compression");
> - return false;
> - }
> -
> if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
> error_setg(errp,
> "Mapped-ram migration is incompatible with postcopy");
> @@ -744,27 +681,6 @@ uint32_t migrate_checkpoint_delay(void)
> return s->parameters.x_checkpoint_delay;
> }
>
> -int migrate_compress_level(void)
> -{
> - MigrationState *s = migrate_get_current();
> -
> - return s->parameters.compress_level;
> -}
> -
> -int migrate_compress_threads(void)
> -{
> - MigrationState *s = migrate_get_current();
> -
> - return s->parameters.compress_threads;
> -}
> -
> -int migrate_compress_wait_thread(void)
> -{
> - MigrationState *s = migrate_get_current();
> -
> - return s->parameters.compress_wait_thread;
> -}
> -
Please also drop the declarations from migration/options.h.
> uint8_t migrate_cpu_throttle_increment(void)
> {
> MigrationState *s = migrate_get_current();
> @@ -786,13 +702,6 @@ bool migrate_cpu_throttle_tailslow(void)
> return s->parameters.cpu_throttle_tailslow;
> }
>
> -int migrate_decompress_threads(void)
> -{
> - MigrationState *s = migrate_get_current();
> -
> - return s->parameters.decompress_threads;
> -}
> -
Please also drop the declaration from migration/options.h.
> uint64_t migrate_downtime_limit(void)
> {
> MigrationState *s = migrate_get_current();
> @@ -938,14 +847,6 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
>
> /* TODO use QAPI_CLONE() instead of duplicating it inline */
> params = g_malloc0(sizeof(*params));
> - params->has_compress_level = true;
> - params->compress_level = s->parameters.compress_level;
> - params->has_compress_threads = true;
> - params->compress_threads = s->parameters.compress_threads;
> - params->has_compress_wait_thread = true;
> - params->compress_wait_thread = s->parameters.compress_wait_thread;
> - params->has_decompress_threads = true;
> - params->decompress_threads = s->parameters.decompress_threads;
> params->has_throttle_trigger_threshold = true;
> params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
> params->has_cpu_throttle_initial = true;
> @@ -1014,10 +915,6 @@ void migrate_params_init(MigrationParameters *params)
> params->tls_creds = g_strdup("");
>
> /* Set has_* up only for parameter checks */
> - params->has_compress_level = true;
> - params->has_compress_threads = true;
> - params->has_compress_wait_thread = true;
> - params->has_decompress_threads = true;
> params->has_throttle_trigger_threshold = true;
> params->has_cpu_throttle_initial = true;
> params->has_cpu_throttle_increment = true;
> @@ -1050,27 +947,6 @@ bool migrate_params_check(MigrationParameters *params, Error **errp)
> {
> ERRP_GUARD();
>
> - if (params->has_compress_level &&
> - (params->compress_level > 9)) {
> - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
> - "a value between 0 and 9");
> - return false;
> - }
> -
> - if (params->has_compress_threads && (params->compress_threads < 1)) {
> - error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
> - "compress_threads",
> - "a value between 1 and 255");
> - return false;
> - }
> -
> - if (params->has_decompress_threads && (params->decompress_threads < 1)) {
> - error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
> - "decompress_threads",
> - "a value between 1 and 255");
> - return false;
> - }
> -
> if (params->has_throttle_trigger_threshold &&
> (params->throttle_trigger_threshold < 1 ||
> params->throttle_trigger_threshold > 100)) {
> @@ -1245,22 +1121,6 @@ static void migrate_params_test_apply(MigrateSetParameters *params,
>
> /* TODO use QAPI_CLONE() instead of duplicating it inline */
>
> - if (params->has_compress_level) {
> - dest->compress_level = params->compress_level;
> - }
> -
> - if (params->has_compress_threads) {
> - dest->compress_threads = params->compress_threads;
> - }
> -
> - if (params->has_compress_wait_thread) {
> - dest->compress_wait_thread = params->compress_wait_thread;
> - }
> -
> - if (params->has_decompress_threads) {
> - dest->decompress_threads = params->decompress_threads;
> - }
> -
> if (params->has_throttle_trigger_threshold) {
> dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
> }
> @@ -1365,30 +1225,6 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
>
> /* TODO use QAPI_CLONE() instead of duplicating it inline */
>
> - if (params->has_compress_level) {
> - warn_report("old compression is deprecated;"
> - " use multifd compression methods instead");
> - s->parameters.compress_level = params->compress_level;
> - }
> -
> - if (params->has_compress_threads) {
> - warn_report("old compression is deprecated;"
> - " use multifd compression methods instead");
> - s->parameters.compress_threads = params->compress_threads;
> - }
> -
> - if (params->has_compress_wait_thread) {
> - warn_report("old compression is deprecated;"
> - " use multifd compression methods instead");
> - s->parameters.compress_wait_thread = params->compress_wait_thread;
> - }
> -
> - if (params->has_decompress_threads) {
> - warn_report("old compression is deprecated;"
> - " use multifd compression methods instead");
> - s->parameters.decompress_threads = params->decompress_threads;
> - }
> -
> if (params->has_throttle_trigger_threshold) {
> s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
> }
> diff --git a/migration/ram-compress.c b/migration/ram-compress.c
> deleted file mode 100644
> index fa4388f6a6..0000000000
> --- a/migration/ram-compress.c
> +++ /dev/null
> @@ -1,564 +0,0 @@
> -/*
> - * QEMU System Emulator
> - *
> - * Copyright (c) 2003-2008 Fabrice Bellard
> - * Copyright (c) 2011-2015 Red Hat Inc
> - *
> - * Authors:
> - * Juan Quintela <quintela@redhat.com>
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a copy
> - * of this software and associated documentation files (the "Software"), to deal
> - * in the Software without restriction, including without limitation the rights
> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> - * copies of the Software, and to permit persons to whom the Software is
> - * furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> - * THE SOFTWARE.
> - */
> -
> -#include "qemu/osdep.h"
> -#include "qemu/cutils.h"
> -
> -#include "ram-compress.h"
> -
> -#include "qemu/error-report.h"
> -#include "qemu/stats64.h"
> -#include "migration.h"
> -#include "options.h"
> -#include "io/channel-null.h"
> -#include "exec/target_page.h"
> -#include "exec/ramblock.h"
> -#include "ram.h"
> -#include "migration-stats.h"
> -
> -static struct {
> - int64_t pages;
> - int64_t busy;
> - double busy_rate;
> - int64_t compressed_size;
> - double compression_rate;
> - /* compression statistics since the beginning of the period */
> - /* amount of count that no free thread to compress data */
> - uint64_t compress_thread_busy_prev;
> - /* amount bytes after compression */
> - uint64_t compressed_size_prev;
> - /* amount of compressed pages */
> - uint64_t compress_pages_prev;
> -} compression_counters;
> -
> -static CompressParam *comp_param;
> -static QemuThread *compress_threads;
> -/* comp_done_cond is used to wake up the migration thread when
> - * one of the compression threads has finished the compression.
> - * comp_done_lock is used to co-work with comp_done_cond.
> - */
> -static QemuMutex comp_done_lock;
> -static QemuCond comp_done_cond;
> -
> -struct DecompressParam {
> - bool done;
> - bool quit;
> - QemuMutex mutex;
> - QemuCond cond;
> - void *des;
> - uint8_t *compbuf;
> - int len;
> - z_stream stream;
> -};
> -typedef struct DecompressParam DecompressParam;
> -
> -static QEMUFile *decomp_file;
> -static DecompressParam *decomp_param;
> -static QemuThread *decompress_threads;
> -static QemuMutex decomp_done_lock;
> -static QemuCond decomp_done_cond;
> -
> -static CompressResult do_compress_ram_page(QEMUFile *f, z_stream *stream,
> - RAMBlock *block, ram_addr_t offset,
> - uint8_t *source_buf);
> -
> -static void *do_data_compress(void *opaque)
> -{
> - CompressParam *param = opaque;
> - RAMBlock *block;
> - ram_addr_t offset;
> - CompressResult result;
> -
> - qemu_mutex_lock(¶m->mutex);
> - while (!param->quit) {
> - if (param->trigger) {
> - block = param->block;
> - offset = param->offset;
> - param->trigger = false;
> - qemu_mutex_unlock(¶m->mutex);
> -
> - result = do_compress_ram_page(param->file, ¶m->stream,
> - block, offset, param->originbuf);
> -
> - qemu_mutex_lock(&comp_done_lock);
> - param->done = true;
> - param->result = result;
> - qemu_cond_signal(&comp_done_cond);
> - qemu_mutex_unlock(&comp_done_lock);
> -
> - qemu_mutex_lock(¶m->mutex);
> - } else {
> - qemu_cond_wait(¶m->cond, ¶m->mutex);
> - }
> - }
> - qemu_mutex_unlock(¶m->mutex);
> -
> - return NULL;
> -}
> -
> -void compress_threads_save_cleanup(void)
> -{
> - int i, thread_count;
> -
> - if (!migrate_compress() || !comp_param) {
> - return;
> - }
> -
> - thread_count = migrate_compress_threads();
> - for (i = 0; i < thread_count; i++) {
> - /*
> - * we use it as a indicator which shows if the thread is
> - * properly init'd or not
> - */
> - if (!comp_param[i].file) {
> - break;
> - }
> -
> - qemu_mutex_lock(&comp_param[i].mutex);
> - comp_param[i].quit = true;
> - qemu_cond_signal(&comp_param[i].cond);
> - qemu_mutex_unlock(&comp_param[i].mutex);
> -
> - qemu_thread_join(compress_threads + i);
> - qemu_mutex_destroy(&comp_param[i].mutex);
> - qemu_cond_destroy(&comp_param[i].cond);
> - deflateEnd(&comp_param[i].stream);
> - g_free(comp_param[i].originbuf);
> - qemu_fclose(comp_param[i].file);
> - comp_param[i].file = NULL;
> - }
> - qemu_mutex_destroy(&comp_done_lock);
> - qemu_cond_destroy(&comp_done_cond);
> - g_free(compress_threads);
> - g_free(comp_param);
> - compress_threads = NULL;
> - comp_param = NULL;
> -}
> -
> -int compress_threads_save_setup(void)
> -{
> - int i, thread_count;
> -
> - if (!migrate_compress()) {
> - return 0;
> - }
> - thread_count = migrate_compress_threads();
> - compress_threads = g_new0(QemuThread, thread_count);
> - comp_param = g_new0(CompressParam, thread_count);
> - qemu_cond_init(&comp_done_cond);
> - qemu_mutex_init(&comp_done_lock);
> - for (i = 0; i < thread_count; i++) {
> - comp_param[i].originbuf = g_try_malloc(qemu_target_page_size());
> - if (!comp_param[i].originbuf) {
> - goto exit;
> - }
> -
> - if (deflateInit(&comp_param[i].stream,
> - migrate_compress_level()) != Z_OK) {
> - g_free(comp_param[i].originbuf);
> - goto exit;
> - }
> -
> - /* comp_param[i].file is just used as a dummy buffer to save data,
> - * set its ops to empty.
> - */
> - comp_param[i].file = qemu_file_new_output(
> - QIO_CHANNEL(qio_channel_null_new()));
> - comp_param[i].done = true;
> - comp_param[i].quit = false;
> - qemu_mutex_init(&comp_param[i].mutex);
> - qemu_cond_init(&comp_param[i].cond);
> - qemu_thread_create(compress_threads + i, "compress",
> - do_data_compress, comp_param + i,
> - QEMU_THREAD_JOINABLE);
> - }
> - return 0;
> -
> -exit:
> - compress_threads_save_cleanup();
> - return -1;
> -}
Please also drop the declarations from migration/ram-compress.h.
> -
> -static CompressResult do_compress_ram_page(QEMUFile *f, z_stream *stream,
> - RAMBlock *block, ram_addr_t offset,
> - uint8_t *source_buf)
> -{
> - uint8_t *p = block->host + offset;
> - size_t page_size = qemu_target_page_size();
> - int ret;
> -
> - assert(qemu_file_buffer_empty(f));
> -
> - if (buffer_is_zero(p, page_size)) {
> - return RES_ZEROPAGE;
> - }
> -
> - /*
> - * copy it to a internal buffer to avoid it being modified by VM
> - * so that we can catch up the error during compression and
> - * decompression
> - */
> - memcpy(source_buf, p, page_size);
> - ret = qemu_put_compression_data(f, stream, source_buf, page_size);
> - if (ret < 0) {
> - qemu_file_set_error(migrate_get_current()->to_dst_file, ret);
> - error_report("compressed data failed!");
> - qemu_fflush(f);
> - return RES_NONE;
> - }
> - return RES_COMPRESS;
> -}
> -
> -static inline void compress_reset_result(CompressParam *param)
> -{
> - param->result = RES_NONE;
> - param->block = NULL;
> - param->offset = 0;
> -}
> -
> -void compress_flush_data(void)
> -{
> - int thread_count = migrate_compress_threads();
> -
> - if (!migrate_compress()) {
> - return;
> - }
> -
> - qemu_mutex_lock(&comp_done_lock);
> - for (int i = 0; i < thread_count; i++) {
> - while (!comp_param[i].done) {
> - qemu_cond_wait(&comp_done_cond, &comp_done_lock);
> - }
> - }
> - qemu_mutex_unlock(&comp_done_lock);
> -
> - for (int i = 0; i < thread_count; i++) {
> - qemu_mutex_lock(&comp_param[i].mutex);
> - if (!comp_param[i].quit) {
> - CompressParam *param = &comp_param[i];
> - compress_send_queued_data(param);
> - assert(qemu_file_buffer_empty(param->file));
> - compress_reset_result(param);
> - }
> - qemu_mutex_unlock(&comp_param[i].mutex);
> - }
> -}
Please also drop the declaration from migration/ram-compress.h.
> -
> -static inline void set_compress_params(CompressParam *param, RAMBlock *block,
> - ram_addr_t offset)
> -{
> - param->block = block;
> - param->offset = offset;
> - param->trigger = true;
> -}
> -
> -/*
> - * Return true when it compress a page
> - */
> -bool compress_page_with_multi_thread(RAMBlock *block, ram_addr_t offset,
> - int (send_queued_data(CompressParam *)))
> -{
> - int thread_count;
> - bool wait = migrate_compress_wait_thread();
> -
> - thread_count = migrate_compress_threads();
> - qemu_mutex_lock(&comp_done_lock);
> -
> - while (true) {
> - for (int i = 0; i < thread_count; i++) {
> - if (comp_param[i].done) {
> - CompressParam *param = &comp_param[i];
> - qemu_mutex_lock(¶m->mutex);
> - param->done = false;
> - send_queued_data(param);
> - assert(qemu_file_buffer_empty(param->file));
> - compress_reset_result(param);
> - set_compress_params(param, block, offset);
> -
> - qemu_cond_signal(¶m->cond);
> - qemu_mutex_unlock(¶m->mutex);
> - qemu_mutex_unlock(&comp_done_lock);
> - return true;
> - }
> - }
> - if (!wait) {
> - qemu_mutex_unlock(&comp_done_lock);
> - compression_counters.busy++;
> - return false;
> - }
> - /*
> - * wait for a free thread if the user specifies
> - * 'compress-wait-thread', otherwise we will post the page out
> - * in the main thread as normal page.
> - */
> - qemu_cond_wait(&comp_done_cond, &comp_done_lock);
> - }
> -}
Please also drop the declaration from migration/ram-compress.h.
> -
> -/* return the size after decompression, or negative value on error */
> -static int
> -qemu_uncompress_data(z_stream *stream, uint8_t *dest, size_t dest_len,
> - const uint8_t *source, size_t source_len)
> -{
> - int err;
> -
> - err = inflateReset(stream);
> - if (err != Z_OK) {
> - return -1;
> - }
> -
> - stream->avail_in = source_len;
> - stream->next_in = (uint8_t *)source;
> - stream->avail_out = dest_len;
> - stream->next_out = dest;
> -
> - err = inflate(stream, Z_NO_FLUSH);
> - if (err != Z_STREAM_END) {
> - return -1;
> - }
> -
> - return stream->total_out;
> -}
> -
> -static void *do_data_decompress(void *opaque)
> -{
> - DecompressParam *param = opaque;
> - unsigned long pagesize;
> - uint8_t *des;
> - int len, ret;
> -
> - qemu_mutex_lock(¶m->mutex);
> - while (!param->quit) {
> - if (param->des) {
> - des = param->des;
> - len = param->len;
> - param->des = 0;
> - qemu_mutex_unlock(¶m->mutex);
> -
> - pagesize = qemu_target_page_size();
> -
> - ret = qemu_uncompress_data(¶m->stream, des, pagesize,
> - param->compbuf, len);
> - if (ret < 0 && migrate_get_current()->decompress_error_check) {
> - error_report("decompress data failed");
> - qemu_file_set_error(decomp_file, ret);
> - }
> -
> - qemu_mutex_lock(&decomp_done_lock);
> - param->done = true;
> - qemu_cond_signal(&decomp_done_cond);
> - qemu_mutex_unlock(&decomp_done_lock);
> -
> - qemu_mutex_lock(¶m->mutex);
> - } else {
> - qemu_cond_wait(¶m->cond, ¶m->mutex);
> - }
> - }
> - qemu_mutex_unlock(¶m->mutex);
> -
> - return NULL;
> -}
> -
> -int wait_for_decompress_done(void)
> -{
> - if (!migrate_compress()) {
> - return 0;
> - }
> -
> - int thread_count = migrate_decompress_threads();
> - qemu_mutex_lock(&decomp_done_lock);
> - for (int i = 0; i < thread_count; i++) {
> - while (!decomp_param[i].done) {
> - qemu_cond_wait(&decomp_done_cond, &decomp_done_lock);
> - }
> - }
> - qemu_mutex_unlock(&decomp_done_lock);
> - return qemu_file_get_error(decomp_file);
> -}
> -
> -void compress_threads_load_cleanup(void)
> -{
> - int i, thread_count;
> -
> - if (!migrate_compress()) {
> - return;
> - }
> - thread_count = migrate_decompress_threads();
> - for (i = 0; i < thread_count; i++) {
> - /*
> - * we use it as a indicator which shows if the thread is
> - * properly init'd or not
> - */
> - if (!decomp_param[i].compbuf) {
> - break;
> - }
> -
> - qemu_mutex_lock(&decomp_param[i].mutex);
> - decomp_param[i].quit = true;
> - qemu_cond_signal(&decomp_param[i].cond);
> - qemu_mutex_unlock(&decomp_param[i].mutex);
> - }
> - for (i = 0; i < thread_count; i++) {
> - if (!decomp_param[i].compbuf) {
> - break;
> - }
> -
> - qemu_thread_join(decompress_threads + i);
> - qemu_mutex_destroy(&decomp_param[i].mutex);
> - qemu_cond_destroy(&decomp_param[i].cond);
> - inflateEnd(&decomp_param[i].stream);
> - g_free(decomp_param[i].compbuf);
> - decomp_param[i].compbuf = NULL;
> - }
> - g_free(decompress_threads);
> - g_free(decomp_param);
> - decompress_threads = NULL;
> - decomp_param = NULL;
> - decomp_file = NULL;
> -}
> -
> -int compress_threads_load_setup(QEMUFile *f)
> -{
> - int i, thread_count;
> -
> - if (!migrate_compress()) {
> - return 0;
> - }
> -
> - /*
> - * set compression_counters memory to zero for a new migration
> - */
> - memset(&compression_counters, 0, sizeof(compression_counters));
> -
> - thread_count = migrate_decompress_threads();
> - decompress_threads = g_new0(QemuThread, thread_count);
> - decomp_param = g_new0(DecompressParam, thread_count);
> - qemu_mutex_init(&decomp_done_lock);
> - qemu_cond_init(&decomp_done_cond);
> - decomp_file = f;
> - for (i = 0; i < thread_count; i++) {
> - if (inflateInit(&decomp_param[i].stream) != Z_OK) {
> - goto exit;
> - }
> -
> - size_t compbuf_size = compressBound(qemu_target_page_size());
> - decomp_param[i].compbuf = g_malloc0(compbuf_size);
> - qemu_mutex_init(&decomp_param[i].mutex);
> - qemu_cond_init(&decomp_param[i].cond);
> - decomp_param[i].done = true;
> - decomp_param[i].quit = false;
> - qemu_thread_create(decompress_threads + i, "decompress",
> - do_data_decompress, decomp_param + i,
> - QEMU_THREAD_JOINABLE);
> - }
> - return 0;
> -exit:
> - compress_threads_load_cleanup();
> - return -1;
> -}
> -
> -void decompress_data_with_multi_threads(QEMUFile *f, void *host, int len)
> -{
> - int thread_count = migrate_decompress_threads();
> - QEMU_LOCK_GUARD(&decomp_done_lock);
> - while (true) {
> - for (int i = 0; i < thread_count; i++) {
> - if (decomp_param[i].done) {
> - decomp_param[i].done = false;
> - qemu_mutex_lock(&decomp_param[i].mutex);
> - qemu_get_buffer(f, decomp_param[i].compbuf, len);
> - decomp_param[i].des = host;
> - decomp_param[i].len = len;
> - qemu_cond_signal(&decomp_param[i].cond);
> - qemu_mutex_unlock(&decomp_param[i].mutex);
> - return;
> - }
> - }
> - qemu_cond_wait(&decomp_done_cond, &decomp_done_lock);
> - }
> -}
> -
> -void populate_compress(MigrationInfo *info)
> -{
> - if (!migrate_compress()) {
> - return;
> - }
> - info->compression = g_malloc0(sizeof(*info->compression));
> - info->compression->pages = compression_counters.pages;
> - info->compression->busy = compression_counters.busy;
> - info->compression->busy_rate = compression_counters.busy_rate;
> - info->compression->compressed_size = compression_counters.compressed_size;
> - info->compression->compression_rate = compression_counters.compression_rate;
> -}
Please also drop the declaration from migration/ram-compress.h.
Not nothing again.
The entire header may well need to go.
Please double-check the entire series for missing header updates.
[...]
QAPI schema
Acked-by: Markus Armbruster <armbru@redhat.com>
next prev parent reply other threads:[~2024-04-26 14:28 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-25 15:09 [PATCH 0/6] migration removals & deprecations Fabiano Rosas
2024-04-25 15:09 ` [PATCH 1/6] migration: Remove 'skipped' field from MigrationStats Fabiano Rosas
2024-04-26 5:26 ` Markus Armbruster
2024-04-25 15:09 ` [PATCH 2/6] migration: Remove 'inc' option from migrate command Fabiano Rosas
2024-04-26 13:25 ` Markus Armbruster
2024-04-26 14:07 ` Markus Armbruster
2024-04-25 15:09 ` [PATCH 3/6] migration: Remove 'blk/-b' option from migrate commands Fabiano Rosas
2024-04-26 13:26 ` Markus Armbruster
2024-04-26 14:05 ` Markus Armbruster
2024-04-26 14:19 ` Fabiano Rosas
2024-04-25 15:09 ` [PATCH 4/6] migration: Remove block migration Fabiano Rosas
2024-04-26 14:15 ` Markus Armbruster
2024-04-25 15:09 ` [PATCH 5/6] migration: Remove non-multifd compression Fabiano Rosas
2024-04-26 14:27 ` Markus Armbruster [this message]
2024-04-25 15:09 ` [PATCH 6/6] migration: Deprecate fd: for file migration Fabiano Rosas
2024-04-26 6:02 ` [PATCH 0/6] migration removals & deprecations Markus Armbruster
2024-04-26 12:51 ` Fabiano Rosas
2024-04-26 13:08 ` Markus Armbruster
2024-04-26 13:15 ` Fabiano Rosas
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=87zftgqjw7.fsf@pond.sub.org \
--to=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=devel@lists.libvirt.org \
--cc=eblake@redhat.com \
--cc=eduardo@habkost.net \
--cc=farosas@suse.de \
--cc=lvivier@redhat.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=thuth@redhat.com \
--cc=wangyanan55@huawei.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.