diff --git a/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch b/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch new file mode 100644 index 0000000000000000000000000000000000000000..0bc4707a244ebc8366648250c75755e8446c6e44 --- /dev/null +++ b/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch @@ -0,0 +1,74 @@ +From ec35c96006851a956a7e401f29af0ffe137c4bb9 Mon Sep 17 00:00:00 2001 +From: Jiadong Zeng +Date: Tue, 8 Feb 2022 22:56:37 +0800 +Subject: [PATCH] add Phytium's CPU models: FT-2000+ and Tengyun-S2500. + +Signed-off-by: Jiadong Zeng +Signed-off-by: Mingwang Li +--- + hw/arm/virt.c | 2 ++ + target/arm/cpu64.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index a4a35584e9..3c972fdab0 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -202,6 +202,8 @@ static const char *valid_cpus[] = { + ARM_CPU_TYPE_NAME("cortex-a57"), + ARM_CPU_TYPE_NAME("cortex-a72"), + ARM_CPU_TYPE_NAME("Kunpeng-920"), ++ ARM_CPU_TYPE_NAME("FT-2000+"), ++ ARM_CPU_TYPE_NAME("Tengyun-S2500"), + ARM_CPU_TYPE_NAME("a64fx"), + ARM_CPU_TYPE_NAME("host"), + ARM_CPU_TYPE_NAME("max"), +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index 556b6f3691..08d886de7b 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -676,6 +676,32 @@ static Property arm_cpu_pauth_property = + static Property arm_cpu_pauth_impdef_property = + DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false); + ++static void aarch64_max_ft2000plus_initfn(Object *obj) ++{ ++ ARMCPU *cpu = ARM_CPU(obj); ++ ++ if (kvm_enabled()) { ++ kvm_arm_set_cpu_features_from_host(cpu); ++ kvm_arm_add_vcpu_properties(obj); ++ } else { ++ aarch64_a72_initfn(obj); ++ cpu->midr = 0x70186622; ++ } ++} ++ ++static void aarch64_max_tengyun_s2500_initfn(Object *obj) ++{ ++ ARMCPU *cpu = ARM_CPU(obj); ++ ++ if (kvm_enabled()) { ++ kvm_arm_set_cpu_features_from_host(cpu); ++ kvm_arm_add_vcpu_properties(obj); ++ } else { ++ aarch64_a72_initfn(obj); ++ cpu->midr = 0x70186632; ++ } ++} ++ + /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host); + * otherwise, a CPU with as many features enabled as our emulation supports. + * The version of '-cpu max' for qemu-system-arm is defined in cpu.c; +@@ -914,6 +940,8 @@ static const ARMCPUInfo aarch64_cpus[] = { + { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, + { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, + { .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn}, ++ { .name = "FT-2000+", .initfn = aarch64_max_ft2000plus_initfn }, ++ { .name = "Tengyun-S2500", .initfn = aarch64_max_tengyun_s2500_initfn }, + { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, + { .name = "max", .initfn = aarch64_max_initfn }, + }; +-- +2.27.0 + diff --git a/block-Add-error-retry-param-setting.patch b/block-Add-error-retry-param-setting.patch new file mode 100644 index 0000000000000000000000000000000000000000..7dcdebeea299503dbab373a21b46e1b599f2ddf0 --- /dev/null +++ b/block-Add-error-retry-param-setting.patch @@ -0,0 +1,227 @@ +From a58fda7b158441c645e143bf658d12914ffbc7b8 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:50 +0800 +Subject: [PATCH] block: Add error retry param setting + +Add "retry_interval" and "retry_timeout" parameter for drive and device +option. These parameter are valid only when werror/rerror=retry. + +eg. --drive file=image,rerror=retry,retry_interval=1000,retry_timeout=5000 + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 13 +++++++-- + blockdev.c | 50 ++++++++++++++++++++++++++++++++++ + hw/block/block.c | 10 +++++++ + include/hw/block/block.h | 7 ++++- + include/sysemu/block-backend.h | 5 ++++ + 5 files changed, 81 insertions(+), 4 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 37e21c473e..d3d90a95a5 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -35,9 +35,6 @@ + + static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); + +-/* block backend default retry interval */ +-#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 +- + typedef struct BlockBackendAioNotifier { + void (*attached_aio_context)(AioContext *new_context, void *opaque); + void (*detach_aio_context)(void *opaque); +@@ -1766,6 +1763,16 @@ void blk_drain_all(void) + bdrv_drain_all_end(); + } + ++void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval) ++{ ++ blk->retry_interval = interval; ++} ++ ++void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout) ++{ ++ blk->retry_timeout = timeout; ++} ++ + static bool blk_error_retry_timeout(BlockBackend *blk) + { + /* No timeout set, infinite retries. */ +diff --git a/blockdev.c b/blockdev.c +index 6f1981635b..10a73fa423 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -480,6 +480,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + const char *buf; + int bdrv_flags = 0; + int on_read_error, on_write_error; ++ int64_t retry_interval, retry_timeout; + bool account_invalid, account_failed; + bool writethrough, read_only; + BlockBackend *blk; +@@ -572,6 +573,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + } + } + ++ retry_interval = qemu_opt_get_number(opts, "retry_interval", ++ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); ++ retry_timeout = qemu_opt_get_number(opts, "retry_timeout", 0); ++ + if (snapshot) { + bdrv_flags |= BDRV_O_SNAPSHOT; + } +@@ -635,6 +640,11 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + + blk_set_enable_write_cache(blk, !writethrough); + blk_set_on_error(blk, on_read_error, on_write_error); ++ if (on_read_error == BLOCKDEV_ON_ERROR_RETRY || ++ on_write_error == BLOCKDEV_ON_ERROR_RETRY) { ++ blk_set_on_error_retry_interval(blk, retry_interval); ++ blk_set_on_error_retry_timeout(blk, retry_timeout); ++ } + + if (!monitor_add_blk(blk, id, errp)) { + blk_unref(blk); +@@ -761,6 +771,14 @@ QemuOptsList qemu_legacy_drive_opts = { + .name = "werror", + .type = QEMU_OPT_STRING, + .help = "write error action", ++ },{ ++ .name = "retry_interval", ++ .type = QEMU_OPT_NUMBER, ++ .help = "interval for retry action in millisecond", ++ },{ ++ .name = "retry_timeout", ++ .type = QEMU_OPT_NUMBER, ++ .help = "timeout for retry action in millisecond", + },{ + .name = "copy-on-read", + .type = QEMU_OPT_BOOL, +@@ -783,6 +801,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, + BlockInterfaceType type; + int max_devs, bus_id, unit_id, index; + const char *werror, *rerror; ++ int64_t retry_interval, retry_timeout; + bool read_only = false; + bool copy_on_read; + const char *filename; +@@ -990,6 +1009,29 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, + qdict_put_str(bs_opts, "rerror", rerror); + } + ++ if (qemu_opt_find(legacy_opts, "retry_interval")) { ++ if ((werror == NULL || strcmp(werror, "retry")) && ++ (rerror == NULL || strcmp(rerror, "retry"))) { ++ error_setg(errp, "retry_interval is only supported " ++ "by werror/rerror=retry"); ++ goto fail; ++ } ++ retry_interval = qemu_opt_get_number(legacy_opts, "retry_interval", ++ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); ++ qdict_put_int(bs_opts, "retry_interval", retry_interval); ++ } ++ ++ if (qemu_opt_find(legacy_opts, "retry_timeout")) { ++ if ((werror == NULL || strcmp(werror, "retry")) && ++ (rerror == NULL || strcmp(rerror, "retry"))) { ++ error_setg(errp, "retry_timeout is only supported " ++ "by werror/rerror=retry"); ++ goto fail; ++ } ++ retry_timeout = qemu_opt_get_number(legacy_opts, "retry_timeout", 0); ++ qdict_put_int(bs_opts, "retry_timeout", retry_timeout); ++ } ++ + /* Actual block device init: Functionality shared with blockdev-add */ + blk = blockdev_init(filename, bs_opts, errp); + bs_opts = NULL; +@@ -3806,6 +3848,14 @@ QemuOptsList qemu_common_drive_opts = { + .name = "werror", + .type = QEMU_OPT_STRING, + .help = "write error action", ++ },{ ++ .name = "retry_interval", ++ .type = QEMU_OPT_NUMBER, ++ .help = "interval for retry action in millisecond", ++ },{ ++ .name = "retry_timeout", ++ .type = QEMU_OPT_NUMBER, ++ .help = "timeout for retry action in millisecond", + },{ + .name = BDRV_OPT_READ_ONLY, + .type = QEMU_OPT_BOOL, +diff --git a/hw/block/block.c b/hw/block/block.c +index d47ebf005a..26c0767552 100644 +--- a/hw/block/block.c ++++ b/hw/block/block.c +@@ -206,6 +206,16 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, + blk_set_enable_write_cache(blk, wce); + blk_set_on_error(blk, rerror, werror); + ++ if (rerror == BLOCKDEV_ON_ERROR_RETRY || ++ werror == BLOCKDEV_ON_ERROR_RETRY) { ++ if (conf->retry_interval >= 0) { ++ blk_set_on_error_retry_interval(blk, conf->retry_interval); ++ } ++ if (conf->retry_timeout >= 0) { ++ blk_set_on_error_retry_timeout(blk, conf->retry_timeout); ++ } ++ } ++ + return true; + } + +diff --git a/include/hw/block/block.h b/include/hw/block/block.h +index 5902c0440a..24fb7d77af 100644 +--- a/include/hw/block/block.h ++++ b/include/hw/block/block.h +@@ -33,6 +33,8 @@ typedef struct BlockConf { + bool share_rw; + BlockdevOnError rerror; + BlockdevOnError werror; ++ int64_t retry_interval; ++ int64_t retry_timeout; + } BlockConf; + + static inline unsigned int get_physical_block_exp(BlockConf *conf) +@@ -79,7 +81,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) + DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \ + BLOCKDEV_ON_ERROR_AUTO), \ + DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ +- BLOCKDEV_ON_ERROR_AUTO) ++ BLOCKDEV_ON_ERROR_AUTO), \ ++ DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ ++ -1), \ ++ DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) + + /* Backend access helpers */ + +diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h +index 56a403883d..887c19ff5d 100644 +--- a/include/sysemu/block-backend.h ++++ b/include/sysemu/block-backend.h +@@ -25,6 +25,9 @@ + */ + #include "block/block.h" + ++/* block backend default retry interval */ ++#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 ++ + /* Callbacks for block device models */ + typedef struct BlockDevOps { + /* +@@ -198,6 +201,8 @@ void blk_inc_in_flight(BlockBackend *blk); + void blk_dec_in_flight(BlockBackend *blk); + void blk_drain(BlockBackend *blk); + void blk_drain_all(void); ++void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval); ++void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout); + void blk_error_retry_reset_timeout(BlockBackend *blk); + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error); +-- +2.27.0 + diff --git a/block-backend-Add-device-specific-retry-callback.patch b/block-backend-Add-device-specific-retry-callback.patch new file mode 100644 index 0000000000000000000000000000000000000000..51981d9d17520697ee69a00ed6418e9e06b1f763 --- /dev/null +++ b/block-backend-Add-device-specific-retry-callback.patch @@ -0,0 +1,54 @@ +From dfda8c57de71f2f10b57cf21b1e36f18d4ed37a3 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:47 +0800 +Subject: [PATCH] block-backend: Add device specific retry callback + +Add retry_request_cb in BlockDevOps to do device specific retry action. +Backend's timer would be registered only when the backend is set 'retry' +on errors and the device supports retry action. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 8 ++++++++ + include/sysemu/block-backend.h | 4 ++++ + 2 files changed, 12 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 257cd775c0..24003adf0b 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1018,6 +1018,14 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, + blk->dev_ops = ops; + blk->dev_opaque = opaque; + ++ if ((blk->on_read_error == BLOCKDEV_ON_ERROR_RETRY || ++ blk->on_write_error == BLOCKDEV_ON_ERROR_RETRY) && ++ ops->retry_request_cb) { ++ blk->retry_timer = aio_timer_new(blk->ctx, QEMU_CLOCK_REALTIME, ++ SCALE_MS, ops->retry_request_cb, ++ opaque); ++ } ++ + /* Are we currently quiesced? Should we enforce this right now? */ + if (blk->quiesce_counter && ops->drained_begin) { + ops->drained_begin(opaque); +diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h +index e5e1524f06..a7a13d47de 100644 +--- a/include/sysemu/block-backend.h ++++ b/include/sysemu/block-backend.h +@@ -70,6 +70,10 @@ typedef struct BlockDevOps { + * Is the device still busy? + */ + bool (*drained_poll)(void *opaque); ++ /* ++ * Runs when retrying failed requests. ++ */ ++ void (*retry_request_cb)(void *opaque); + } BlockDevOps; + + /* This struct is embedded in (the private) BlockBackend struct and contains +-- +2.27.0 + diff --git a/block-backend-Add-timeout-support-for-retry.patch b/block-backend-Add-timeout-support-for-retry.patch new file mode 100644 index 0000000000000000000000000000000000000000..b1fb6c9180f4739b5f0040a916b5d9ed29165e14 --- /dev/null +++ b/block-backend-Add-timeout-support-for-retry.patch @@ -0,0 +1,75 @@ +From 953590f4854d75e6051237f668c9fb393235f471 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:49 +0800 +Subject: [PATCH] block-backend: Add timeout support for retry + +Retry should only be triggered when timeout is not reached, so let's check +timeout before retry. Device should also reset retry_start_time after +successful retry. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 25 ++++++++++++++++++++++++- + include/sysemu/block-backend.h | 1 + + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 5a016d32fa..37e21c473e 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1766,6 +1766,29 @@ void blk_drain_all(void) + bdrv_drain_all_end(); + } + ++static bool blk_error_retry_timeout(BlockBackend *blk) ++{ ++ /* No timeout set, infinite retries. */ ++ if (!blk->retry_timeout) { ++ return false; ++ } ++ ++ /* The first time an error occurs. */ ++ if (!blk->retry_start_time) { ++ blk->retry_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); ++ return false; ++ } ++ ++ return qemu_clock_get_ms(QEMU_CLOCK_REALTIME) > (blk->retry_start_time + ++ blk->retry_timeout); ++} ++ ++void blk_error_retry_reset_timeout(BlockBackend *blk) ++{ ++ if (blk->retry_timer && blk->retry_start_time) ++ blk->retry_start_time = 0; ++} ++ + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error) + { +@@ -1794,7 +1817,7 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, + case BLOCKDEV_ON_ERROR_IGNORE: + return BLOCK_ERROR_ACTION_IGNORE; + case BLOCKDEV_ON_ERROR_RETRY: +- return (blk->retry_timer) ? ++ return (blk->retry_timer && !blk_error_retry_timeout(blk)) ? + BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_AUTO: + default: +diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h +index a7a13d47de..56a403883d 100644 +--- a/include/sysemu/block-backend.h ++++ b/include/sysemu/block-backend.h +@@ -198,6 +198,7 @@ void blk_inc_in_flight(BlockBackend *blk); + void blk_dec_in_flight(BlockBackend *blk); + void blk_drain(BlockBackend *blk); + void blk_drain_all(void); ++void blk_error_retry_reset_timeout(BlockBackend *blk); + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error); + BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read); +-- +2.27.0 + diff --git a/block-backend-Enable-retry-action-on-errors.patch b/block-backend-Enable-retry-action-on-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..a1f274dcd34059725ef2ce618998f0d06b59be13 --- /dev/null +++ b/block-backend-Enable-retry-action-on-errors.patch @@ -0,0 +1,43 @@ +From 2e1c75e5a0339d2bf417e5a4437d8e627a303286 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:48 +0800 +Subject: [PATCH] block-backend: Enable retry action on errors + +Enable retry action when backend's retry timer is available. It would +trigger the timer to do device specific retry action. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 24003adf0b..5a016d32fa 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1793,6 +1793,9 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, + return BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_IGNORE: + return BLOCK_ERROR_ACTION_IGNORE; ++ case BLOCKDEV_ON_ERROR_RETRY: ++ return (blk->retry_timer) ? ++ BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_AUTO: + default: + abort(); +@@ -1840,6 +1843,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action, + qemu_system_vmstop_request_prepare(); + send_qmp_error_event(blk, action, is_read, error); + qemu_system_vmstop_request(RUN_STATE_IO_ERROR); ++ } else if (action == BLOCK_ERROR_ACTION_RETRY) { ++ timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ++ blk->retry_interval); ++ send_qmp_error_event(blk, action, is_read, error); + } else { + send_qmp_error_event(blk, action, is_read, error); + } +-- +2.27.0 + diff --git a/block-backend-Introduce-retry-timer.patch b/block-backend-Introduce-retry-timer.patch new file mode 100644 index 0000000000000000000000000000000000000000..adf955b99b80d943220e29a89770b281f67fabad --- /dev/null +++ b/block-backend-Introduce-retry-timer.patch @@ -0,0 +1,70 @@ +From 4dc180e87fb641f64fce7be3a0807488d0cc0a51 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:46 +0800 +Subject: [PATCH] block-backend: Introduce retry timer + +Add a timer to regularly trigger retry on errors. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 12ef80ea17..257cd775c0 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -35,6 +35,9 @@ + + static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); + ++/* block backend default retry interval */ ++#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 ++ + typedef struct BlockBackendAioNotifier { + void (*attached_aio_context)(AioContext *new_context, void *opaque); + void (*detach_aio_context)(void *opaque); +@@ -95,6 +98,15 @@ struct BlockBackend { + * Accessed with atomic ops. + */ + unsigned int in_flight; ++ ++ /* Timer for retry on errors. */ ++ QEMUTimer *retry_timer; ++ /* Interval in ms to trigger next retry. */ ++ int64_t retry_interval; ++ /* Start time of the first error. Used to check timeout. */ ++ int64_t retry_start_time; ++ /* Retry timeout. 0 represents infinite retry. */ ++ int64_t retry_timeout; + }; + + typedef struct BlockBackendAIOCB { +@@ -353,6 +365,11 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) + blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT; + blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; + ++ blk->retry_timer = NULL; ++ blk->retry_interval = BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL; ++ blk->retry_start_time = 0; ++ blk->retry_timeout = 0; ++ + block_acct_init(&blk->stats); + + qemu_co_queue_init(&blk->queued_requests); +@@ -471,6 +488,10 @@ static void blk_delete(BlockBackend *blk) + QTAILQ_REMOVE(&block_backends, blk, link); + drive_info_del(blk->legacy_dinfo); + block_acct_cleanup(&blk->stats); ++ if (blk->retry_timer) { ++ timer_del(blk->retry_timer); ++ timer_free(blk->retry_timer); ++ } + g_free(blk); + } + +-- +2.27.0 + diff --git a/cpu-add-Cortex-A72-processor-kvm-target-support.patch b/cpu-add-Cortex-A72-processor-kvm-target-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..9a83a8d560cde00b49675184bb86c780c0a33691 --- /dev/null +++ b/cpu-add-Cortex-A72-processor-kvm-target-support.patch @@ -0,0 +1,51 @@ +From f0da7fa5230b5f771570b2c12288e4a56a20dd97 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 8 Feb 2022 22:18:55 +0800 +Subject: [PATCH] cpu: add Cortex-A72 processor kvm target support + +The ARM Cortex-A72 is ARMv8-A micro-architecture, +add kvm target to ARM Cortex-A72 processor definition. + +Signed-off-by: Xu Yandong +Signed-off-by: Mingwang Li +--- + target/arm/cpu64.c | 1 + + target/arm/kvm-consts.h | 3 +++ + 2 files changed, 4 insertions(+) + +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index aaca79f7c3..556b6f3691 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -202,6 +202,7 @@ static void aarch64_a72_initfn(Object *obj) + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,cortex-a72"; ++ cpu->kvm_target = QEMU_KVM_ARM_TARGET_GENERIC_V8; + set_feature(&cpu->env, ARM_FEATURE_V8); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); +diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h +index 580f1c1fee..5f1311ade7 100644 +--- a/target/arm/kvm-consts.h ++++ b/target/arm/kvm-consts.h +@@ -130,6 +130,8 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED); + #define QEMU_KVM_ARM_TARGET_CORTEX_A57 2 + #define QEMU_KVM_ARM_TARGET_XGENE_POTENZA 3 + #define QEMU_KVM_ARM_TARGET_CORTEX_A53 4 ++/* Generic ARM v8 target */ ++#define QEMU_KVM_ARM_TARGET_GENERIC_V8 5 + + /* There's no kernel define for this: sentinel value which + * matches no KVM target value for either 64 or 32 bit +@@ -141,6 +143,7 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8); + MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57); + MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA); + MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53); ++MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_GENERIC_V8, KVM_ARM_TARGET_GENERIC_V8); + + #define CP_REG_ARM64 0x6000000000000000ULL + #define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000 +-- +2.27.0 + diff --git a/cpu-add-Kunpeng-920-cpu-support.patch b/cpu-add-Kunpeng-920-cpu-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..5e24be91c6cf13417cb239f561c60bd4704c0711 --- /dev/null +++ b/cpu-add-Kunpeng-920-cpu-support.patch @@ -0,0 +1,68 @@ +From 8ebab06c4824626ab4d7204133cd1e7b9c67f468 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 8 Feb 2022 21:36:22 +0800 +Subject: [PATCH] cpu: add Kunpeng-920 cpu support + +Add the Kunpeng-920 CPU model + +Signed-off-by: Xu Yandong +Signed-off-by: Mingwang Li +--- + hw/arm/virt.c | 1 + + target/arm/cpu64.c | 21 +++++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 30da05dfe0..a4a35584e9 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -201,6 +201,7 @@ static const char *valid_cpus[] = { + ARM_CPU_TYPE_NAME("cortex-a53"), + ARM_CPU_TYPE_NAME("cortex-a57"), + ARM_CPU_TYPE_NAME("cortex-a72"), ++ ARM_CPU_TYPE_NAME("Kunpeng-920"), + ARM_CPU_TYPE_NAME("a64fx"), + ARM_CPU_TYPE_NAME("host"), + ARM_CPU_TYPE_NAME("max"), +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index 019edc66c9..aaca79f7c3 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -248,6 +248,26 @@ static void aarch64_a72_initfn(Object *obj) + define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); + } + ++static void aarch64_kunpeng_920_initfn(Object *obj) ++{ ++ ARMCPU *cpu = ARM_CPU(obj); ++ ++ /* ++ * Hisilicon Kunpeng-920 CPU is similar to cortex-a72, ++ * so first initialize cpu data as cortex-a72, ++ * and then update the special register. ++ */ ++ aarch64_a72_initfn(obj); ++ ++ cpu->midr = 0x480fd010; ++ cpu->ctr = 0x84448004; ++ cpu->isar.id_aa64pfr0 = 0x11001111; ++ cpu->isar.id_aa64dfr0 = 0x110305408; ++ cpu->isar.id_aa64isar0 = 0x10211120; ++ cpu->isar.id_aa64mmfr0 = 0x101125; ++ cpu->kvm_target = KVM_ARM_TARGET_GENERIC_V8; ++} ++ + void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) + { + /* +@@ -892,6 +912,7 @@ static const ARMCPUInfo aarch64_cpus[] = { + { .name = "cortex-a57", .initfn = aarch64_a57_initfn }, + { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, + { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, ++ { .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn}, + { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, + { .name = "max", .initfn = aarch64_max_initfn }, + }; +-- +2.27.0 + diff --git a/cpu-parse-feature-to-avoid-failure.patch b/cpu-parse-feature-to-avoid-failure.patch new file mode 100644 index 0000000000000000000000000000000000000000..4ae42d904b815b115399e9560f3e456de96c712f --- /dev/null +++ b/cpu-parse-feature-to-avoid-failure.patch @@ -0,0 +1,68 @@ +From ef83cde8dd2c9b404527354489b14d2bd238733d Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 8 Feb 2022 20:48:17 +0800 +Subject: [PATCH] cpu: parse +/- feature to avoid failure + +To avoid cpu feature parse failure, +/- feature is added. + +Signed-off-by: Xu Yandong +Signed-off-by: Mingwang Li +--- + target/arm/cpu64.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index 15245a60a8..019edc66c9 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -933,10 +933,47 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs) + return g_strdup("aarch64"); + } + ++/* Parse "+feature,-feature,feature=foo" CPU feature string ++ */ ++static void arm_cpu_parse_featurestr(const char *typename, char *features, ++ Error **errp ) ++{ ++ char *featurestr; ++ char *val; ++ static bool cpu_globals_initialized; ++ ++ if (cpu_globals_initialized) { ++ return; ++ } ++ cpu_globals_initialized = true; ++ ++ featurestr = features ? strtok(features, ",") : NULL; ++ while (featurestr) { ++ val = strchr(featurestr, '='); ++ if (val) { ++ GlobalProperty *prop = g_new0(typeof(*prop), 1); ++ *val = 0; ++ val++; ++ prop->driver = typename; ++ prop->property = g_strdup(featurestr); ++ prop->value = g_strdup(val); ++ qdev_prop_register_global(prop); ++ } else if (featurestr[0] == '+' || featurestr[0] == '-') { ++ warn_report("Ignore %s feature\n", featurestr); ++ } else { ++ error_setg(errp, "Expected key=value format, found %s.", ++ featurestr); ++ return; ++ } ++ featurestr = strtok(NULL, ","); ++ } ++} ++ + static void aarch64_cpu_class_init(ObjectClass *oc, void *data) + { + CPUClass *cc = CPU_CLASS(oc); + ++ cc->parse_features = arm_cpu_parse_featurestr; + cc->gdb_read_register = aarch64_cpu_gdb_read_register; + cc->gdb_write_register = aarch64_cpu_gdb_write_register; + cc->gdb_num_core_regs = 34; +-- +2.27.0 + diff --git a/doc-Update-multi-thread-compression-doc.patch b/doc-Update-multi-thread-compression-doc.patch new file mode 100644 index 0000000000000000000000000000000000000000..ad47a0b8678136179b476c33d975b0f033745b75 --- /dev/null +++ b/doc-Update-multi-thread-compression-doc.patch @@ -0,0 +1,86 @@ +From 213bd45d2c5337f10216c69c13f0438dd40c58d8 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 16:36:47 +0800 +Subject: [PATCH] doc: Update multi-thread compression doc + +Modify the doc to fit the previous changes. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + docs/multi-thread-compression.txt | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/docs/multi-thread-compression.txt b/docs/multi-thread-compression.txt +index bb88c6bdf1..d429963cb0 100644 +--- a/docs/multi-thread-compression.txt ++++ b/docs/multi-thread-compression.txt +@@ -33,14 +33,15 @@ thread compression can be used to accelerate the compression process. + + The decompression speed of Zlib is at least 4 times as quick as + compression, if the source and destination CPU have equal speed, +-keeping the compression thread count 4 times the decompression +-thread count can avoid resource waste. ++and you choose Zlib as compression method, keeping the compression ++thread count 4 times the decompression thread count can avoid resource waste. + + Compression level can be used to control the compression speed and the +-compression ratio. High compression ratio will take more time, level 0 +-stands for no compression, level 1 stands for the best compression +-speed, and level 9 stands for the best compression ratio. Users can +-select a level number between 0 and 9. ++compression ratio. High compression ratio will take more time, ++level 1 stands for the best compression speed, and higher level means higher ++compression ration. For Zlib, users can select a level number between 0 and 9, ++where level 0 stands for no compression. For Zstd, users can select a ++level number between 1 and 22. + + + When to use the multiple thread compression in live migration +@@ -116,16 +117,19 @@ to support the multiple thread compression migration: + 2. Activate compression on the source: + {qemu} migrate_set_capability compress on + +-3. Set the compression thread count on source: ++3. Set the compression method: ++ {qemu} migrate_set_parameter compress_method zstd ++ ++4. Set the compression thread count on source: + {qemu} migrate_set_parameter compress_threads 12 + +-4. Set the compression level on the source: ++5. Set the compression level on the source: + {qemu} migrate_set_parameter compress_level 1 + +-5. Set the decompression thread count on destination: ++6. Set the decompression thread count on destination: + {qemu} migrate_set_parameter decompress_threads 3 + +-6. Start outgoing migration: ++7. Start outgoing migration: + {qemu} migrate -d tcp:destination.host:4444 + {qemu} info migrate + Capabilities: ... compress: on +@@ -136,6 +140,7 @@ The following are the default settings: + compress_threads: 8 + decompress_threads: 2 + compress_level: 1 (which means best speed) ++ compress_method: zlib + + So, only the first two steps are required to use the multiple + thread compression in migration. You can do more if the default +@@ -143,7 +148,7 @@ settings are not appropriate. + + TODO + ==== +-Some faster (de)compression method such as LZ4 and Quicklz can help +-to reduce the CPU consumption when doing (de)compression. If using +-these faster (de)compression method, less (de)compression threads ++Comparing to Zlib, Some faster (de)compression method such as LZ4 ++and Quicklz can help to reduce the CPU consumption when doing (de)compression. ++If using these faster (de)compression method, less (de)compression threads + are needed when doing the migration. +-- +2.27.0 + diff --git a/migration-Add-compress_level-sanity-check.patch b/migration-Add-compress_level-sanity-check.patch new file mode 100644 index 0000000000000000000000000000000000000000..bcf2e73fb535216ed26d679a092329a32fb2eac6 --- /dev/null +++ b/migration-Add-compress_level-sanity-check.patch @@ -0,0 +1,66 @@ +From 84780210ac31e430d59b0c6d3d9f522c626b6380 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 16:23:15 +0800 +Subject: [PATCH] migration: Add compress_level sanity check + +Zlib compression has level from 1 to 9. However Zstd compression has level +from 1 to 22 (level >= 20 not recommanded). Let's do sanity check here +to make sure a vaild compress_level is given by user. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + migration/migration.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 07dc059251..f86dd8cccd 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1320,14 +1320,40 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, + } + } + ++static bool compress_level_check(MigrationParameters *params, Error **errp) ++{ ++ switch (params->compress_method) { ++ case COMPRESS_METHOD_ZLIB: ++ if (params->compress_level > 9 || params->compress_level < 1) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", ++ "a value in the range of 0 to 9 for Zlib method"); ++ return false; ++ } ++ break; ++#ifdef CONFIG_ZSTD ++ case COMPRESS_METHOD_ZSTD: ++ if (params->compress_level > 19 || params->compress_level < 1) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", ++ "a value in the range of 1 to 19 for Zstd method"); ++ return false; ++ } ++ break; ++#endif ++ default: ++ error_setg(errp, "Checking compress_level failed for unknown reason"); ++ return false; ++ } ++ ++ return true; ++} ++ + /* + * Check whether the parameters are valid. Error will be put into errp + * (if provided). Return true if valid, otherwise false. + */ + static bool migrate_params_check(MigrationParameters *params, Error **errp) + { +- if (params->has_compress_level && +- (params->compress_level > 9)) { ++ if (params->has_compress_level && !compress_level_check(params, errp)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", + "a value between 0 and 9"); + return false; +-- +2.27.0 + diff --git a/migration-Add-multi-thread-compress-method.patch b/migration-Add-multi-thread-compress-method.patch new file mode 100644 index 0000000000000000000000000000000000000000..9e259c8b2bb6922ae26cb5bec98165ca3d3dbece --- /dev/null +++ b/migration-Add-multi-thread-compress-method.patch @@ -0,0 +1,238 @@ +From 39d851b5d5517fbcecc8d16229ae72ca152899b7 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 14:57:54 +0800 +Subject: [PATCH] migration: Add multi-thread compress method + +A multi-thread compress method parameter is added to hold the method we +are going to use. By default the 'zlib' method is used to maintain the +compatibility as before. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + hw/core/qdev-properties-system.c | 11 +++++++++++ + include/hw/qdev-properties.h | 4 ++++ + migration/migration.c | 11 +++++++++++ + monitor/hmp-cmds.c | 13 +++++++++++++ + qapi/migration.json | 26 +++++++++++++++++++++++++- + 5 files changed, 64 insertions(+), 1 deletion(-) + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index a91f60567a..8c265bed6f 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -1119,3 +1119,14 @@ const PropertyInfo qdev_prop_uuid = { + .set = set_uuid, + .set_default_value = set_default_uuid_auto, + }; ++ ++/* --- CompressMethod --- */ ++const PropertyInfo qdev_prop_compress_method = { ++ .name = "CompressMethod", ++ .description = "multi-thread compression method, " ++ "zlib", ++ .enum_table = &CompressMethod_lookup, ++ .get = qdev_propinfo_get_enum, ++ .set = qdev_propinfo_set_enum, ++ .set_default_value = qdev_propinfo_set_default_value_enum, ++}; +diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h +index f7925f67d0..ea129d65a6 100644 +--- a/include/hw/qdev-properties.h ++++ b/include/hw/qdev-properties.h +@@ -58,6 +58,7 @@ extern const PropertyInfo qdev_prop_int64; + extern const PropertyInfo qdev_prop_size; + extern const PropertyInfo qdev_prop_string; + extern const PropertyInfo qdev_prop_on_off_auto; ++extern const PropertyInfo qdev_prop_compress_method; + extern const PropertyInfo qdev_prop_size32; + extern const PropertyInfo qdev_prop_arraylen; + extern const PropertyInfo qdev_prop_link; +@@ -161,6 +162,9 @@ extern const PropertyInfo qdev_prop_link; + DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*) + #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto) ++#define DEFINE_PROP_COMPRESS_METHOD(_n, _s, _f, _d) \ ++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_compress_method, \ ++ CompressMethod) + #define DEFINE_PROP_SIZE32(_n, _s, _f, _d) \ + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size32, uint32_t) + +diff --git a/migration/migration.c b/migration/migration.c +index abaf6f9e3d..fa3db87d75 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -83,6 +83,7 @@ + #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_MIGRATE_COMPRESS_METHOD COMPRESS_METHOD_ZLIB + /* Define default autoconverge cpu throttle migration parameters */ + #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50 + #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20 +@@ -855,6 +856,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) + params->compress_wait_thread = s->parameters.compress_wait_thread; + params->has_decompress_threads = true; + params->decompress_threads = s->parameters.decompress_threads; ++ params->has_compress_method = true; ++ params->compress_method = s->parameters.compress_method; + params->has_throttle_trigger_threshold = true; + params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; + params->has_cpu_throttle_initial = true; +@@ -1491,6 +1494,10 @@ static void migrate_params_test_apply(MigrateSetParameters *params, + dest->decompress_threads = params->decompress_threads; + } + ++ if (params->has_compress_method) { ++ dest->compress_method = params->compress_method; ++ } ++ + if (params->has_throttle_trigger_threshold) { + dest->throttle_trigger_threshold = params->throttle_trigger_threshold; + } +@@ -4159,6 +4166,9 @@ static Property migration_properties[] = { + DEFINE_PROP_UINT8("x-decompress-threads", MigrationState, + parameters.decompress_threads, + DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT), ++ DEFINE_PROP_COMPRESS_METHOD("compress-method", MigrationState, ++ parameters.compress_method, ++ DEFAULT_MIGRATE_COMPRESS_METHOD), + DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState, + parameters.throttle_trigger_threshold, + DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD), +@@ -4275,6 +4285,7 @@ static void migration_instance_init(Object *obj) + params->has_compress_level = true; + params->has_compress_threads = true; + params->has_decompress_threads = true; ++ params->has_compress_method = true; + params->has_throttle_trigger_threshold = true; + params->has_cpu_throttle_initial = true; + params->has_cpu_throttle_increment = true; +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index 9c91bf93e9..294652034e 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -45,6 +45,7 @@ + #include "qapi/qapi-visit-net.h" + #include "qapi/qapi-visit-migration.h" + #include "qapi/qmp/qdict.h" ++#include "qapi/qapi-visit-migration.h" + #include "qapi/qmp/qerror.h" + #include "qapi/string-input-visitor.h" + #include "qapi/string-output-visitor.h" +@@ -429,6 +430,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) + MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS), + params->decompress_threads); + assert(params->has_throttle_trigger_threshold); ++ monitor_printf(mon, "%s: %s\n", ++ MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_METHOD), ++ CompressMethod_str(params->compress_method)); + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD), + params->throttle_trigger_threshold); +@@ -1191,6 +1195,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) + MigrateSetParameters *p = g_new0(MigrateSetParameters, 1); + uint64_t valuebw = 0; + uint64_t cache_size; ++ CompressMethod compress_method; + Error *err = NULL; + int val, ret; + +@@ -1216,6 +1221,14 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) + p->has_decompress_threads = true; + visit_type_uint8(v, param, &p->decompress_threads, &err); + break; ++ case MIGRATION_PARAMETER_COMPRESS_METHOD: ++ p->has_compress_method = true; ++ visit_type_CompressMethod(v, param, &compress_method, &err); ++ if (err) { ++ break; ++ } ++ p->compress_method = compress_method; ++ break; + case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD: + p->has_throttle_trigger_threshold = true; + visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err); +diff --git a/qapi/migration.json b/qapi/migration.json +index bbfd48cf0b..3a76907ea9 100644 +--- a/qapi/migration.json ++++ b/qapi/migration.json +@@ -596,6 +596,19 @@ + 'bitmaps': [ 'BitmapMigrationBitmapAlias' ] + } } + ++## ++# @CompressMethod: ++# ++# An enumeration of multi-thread compression methods. ++# ++# @zlib: use zlib compression method. ++# ++# Since: 5.0 ++# ++## ++{ 'enum': 'CompressMethod', ++ 'data': [ 'zlib' ] } ++ + ## + # @MigrationParameter: + # +@@ -632,6 +645,9 @@ + # compression, so set the decompress-threads to the number about 1/4 + # of compress-threads is adequate. + # ++# @compress-method: Which multi-thread compression method to use. ++# Defaults to none. (Since 5.0) ++# + # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period + # to trigger throttling. It is expressed as percentage. + # The default value is 50. (Since 5.0) +@@ -758,7 +774,7 @@ + 'data': ['announce-initial', 'announce-max', + 'announce-rounds', 'announce-step', + 'compress-level', 'compress-threads', 'decompress-threads', +- 'compress-wait-thread', 'throttle-trigger-threshold', ++ 'compress-wait-thread', 'compress-method', 'throttle-trigger-threshold', + 'cpu-throttle-initial', 'cpu-throttle-increment', + 'cpu-throttle-tailslow', + 'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth', +@@ -797,6 +813,9 @@ + # + # @decompress-threads: decompression thread count + # ++# @compress-method: Set compression method to use in multi-thread compression. ++# Defaults to none. (Since 5.0) ++# + # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period + # to trigger throttling. It is expressed as percentage. + # The default value is 50. (Since 5.0) +@@ -930,6 +949,7 @@ + '*compress-threads': 'uint8', + '*compress-wait-thread': 'bool', + '*decompress-threads': 'uint8', ++ '*compress-method': 'CompressMethod', + '*throttle-trigger-threshold': 'uint8', + '*cpu-throttle-initial': 'uint8', + '*cpu-throttle-increment': 'uint8', +@@ -995,6 +1015,9 @@ + # + # @decompress-threads: decompression thread count + # ++# @compress-method: Which multi-thread compression method to use. ++# Defaults to none. (Since 5.0) ++# + # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period + # to trigger throttling. It is expressed as percentage. + # The default value is 50. (Since 5.0) +@@ -1128,6 +1151,7 @@ + '*compress-threads': 'uint8', + '*compress-wait-thread': 'bool', + '*decompress-threads': 'uint8', ++ '*compress-method': 'CompressMethod', + '*throttle-trigger-threshold': 'uint8', + '*cpu-throttle-initial': 'uint8', + '*cpu-throttle-increment': 'uint8', +-- +2.27.0 + diff --git a/migration-Add-multi-thread-compress-ops.patch b/migration-Add-multi-thread-compress-ops.patch new file mode 100644 index 0000000000000000000000000000000000000000..5787db398bb5e5d56abc47ae0d331e65255ecd9f --- /dev/null +++ b/migration-Add-multi-thread-compress-ops.patch @@ -0,0 +1,443 @@ +From 5e4bc7ceaf81a4932c92e479e9add947b698395b Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 15:57:31 +0800 +Subject: [PATCH] migration: Add multi-thread compress ops + +Add the MigrationCompressOps and MigrationDecompressOps structures to make +the compression method configurable for multi-thread compression migration. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + migration/migration.c | 9 ++ + migration/migration.h | 1 + + migration/ram.c | 269 ++++++++++++++++++++++++++++++------------ + 3 files changed, 201 insertions(+), 78 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index fa3db87d75..07dc059251 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2456,6 +2456,15 @@ int migrate_decompress_threads(void) + return s->parameters.decompress_threads; + } + ++CompressMethod migrate_compress_method(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.compress_method; ++} ++ + bool migrate_dirty_bitmaps(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index 8130b703eb..4ed4f555da 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -355,6 +355,7 @@ int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); + int migrate_decompress_threads(void); ++CompressMethod migrate_compress_method(void); + bool migrate_use_events(void); + bool migrate_postcopy_blocktime(void); + bool migrate_background_snapshot(void); +diff --git a/migration/ram.c b/migration/ram.c +index 1176816fba..069560e7f9 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -417,6 +417,9 @@ struct CompressParam { + /* internally used fields */ + z_stream stream; + uint8_t *originbuf; ++ ++ /* for zlib compression */ ++ z_stream stream; + }; + typedef struct CompressParam CompressParam; + +@@ -428,12 +431,29 @@ struct DecompressParam { + void *des; + uint8_t *compbuf; + int len; ++ ++ /* for zlib compression */ + z_stream stream; + }; + typedef struct DecompressParam DecompressParam; + ++typedef struct { ++ int (*save_setup)(CompressParam *param); ++ void (*save_cleanup)(CompressParam *param); ++ ssize_t (*compress_data)(CompressParam *param, size_t size); ++} MigrationCompressOps; ++ ++typedef struct { ++ int (*load_setup)(DecompressParam *param); ++ void (*load_cleanup)(DecompressParam *param); ++ int (*decompress_data)(DecompressParam *param, uint8_t *dest, size_t size); ++ int (*check_len)(int len); ++} MigrationDecompressOps; ++ + static CompressParam *comp_param; + static QemuThread *compress_threads; ++static MigrationCompressOps *compress_ops; ++static MigrationDecompressOps *decompress_ops; + /* 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. +@@ -451,6 +471,157 @@ static QemuCond decomp_done_cond; + + static bool do_compress_ram_page(CompressParam *param, RAMBlock *block); + ++static int zlib_save_setup(CompressParam *param) ++{ ++ if (deflateInit(¶m->stream, ++ migrate_compress_level()) != Z_OK) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static ssize_t zlib_compress_data(CompressParam *param, size_t size) ++ ++ int err; ++ uint8_t *dest = NULL; ++ z_stream *stream = ¶m->stream; ++ uint8_t *p = param->originbuf; ++ QEMUFile *f = f = param->file; ++ ssize_t blen = qemu_put_compress_start(f, &dest); ++ ++ if (blen < compressBound(size)) { ++ return -1; ++ } ++ ++ err = deflateReset(stream); ++ if (err != Z_OK) { ++ return -1; ++ } ++ ++ stream->avail_in = size; ++ stream->next_in = p; ++ stream->avail_out = blen; ++ stream->next_out = dest; ++ ++ err = deflate(stream, Z_FINISH); ++ if (err != Z_STREAM_END) { ++ return -1; ++ } ++ ++ blen = stream->next_out - dest; ++ if (blen < 0) { ++ return -1; ++ } ++ ++ qemu_put_compress_end(f, blen); ++ return blen + sizeof(int32_t); ++} ++ ++static void zlib_save_cleanup(CompressParam *param) ++{ ++ deflateEnd(¶m->stream); ++} ++ ++static int zlib_load_setup(DecompressParam *param) ++{ ++ if (inflateInit(¶m->stream) != Z_OK) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++zlib_decompress_data(DecompressParam *param, uint8_t *dest, size_t size) ++{ ++ int err; ++ ++ z_stream *stream = ¶m->stream; ++ ++ err = inflateReset(stream); ++ if (err != Z_OK) { ++ return -1; ++ } ++ ++ stream->avail_in = param->len; ++ stream->next_in = param->compbuf; ++ stream->avail_out = size; ++ stream->next_out = dest; ++ ++ err = inflate(stream, Z_NO_FLUSH); ++ if (err != Z_STREAM_END) { ++ return -1; ++ } ++ ++ return stream->total_out; ++} ++ ++static void zlib_load_cleanup(DecompressParam *param) ++{ ++ inflateEnd(¶m->stream); ++} ++ ++static int zlib_check_len(int len) ++{ ++ return len < 0 || len > compressBound(TARGET_PAGE_SIZE); ++} ++ ++static int set_compress_ops(void) ++{ ++ compress_ops = g_new0(MigrationCompressOps, 1); ++ ++ switch (migrate_compress_method()) { ++ case COMPRESS_METHOD_ZLIB: ++ compress_ops->save_setup = zlib_save_setup; ++ compress_ops->save_cleanup = zlib_save_cleanup; ++ compress_ops->compress_data = zlib_compress_data; ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int set_decompress_ops(void) ++{ ++ decompress_ops = g_new0(MigrationDecompressOps, 1); ++ ++ switch (migrate_compress_method()) { ++ case COMPRESS_METHOD_ZLIB: ++ decompress_ops->load_setup = zlib_load_setup; ++ decompress_ops->load_cleanup = zlib_load_cleanup; ++ decompress_ops->decompress_data = zlib_decompress_data; ++ decompress_ops->check_len = zlib_check_len; ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void clean_compress_ops(void) ++{ ++ compress_ops->save_setup = NULL; ++ compress_ops->save_cleanup = NULL; ++ compress_ops->compress_data = NULL; ++ ++ g_free(compress_ops); ++ compress_ops = NULL; ++} ++ ++static void clean_decompress_ops(void) ++{ ++ decompress_ops->load_setup = NULL; ++ decompress_ops->load_cleanup = NULL; ++ decompress_ops->decompress_data = NULL; ++ ++ g_free(decompress_ops); ++ decompress_ops = NULL; ++} ++ + static void *do_data_compress(void *opaque) + { + CompressParam *param = opaque; +@@ -508,7 +679,7 @@ static void compress_threads_save_cleanup(void) + 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); ++ compress_ops->save_cleanup(&comp_param[i]); + g_free(comp_param[i].originbuf); + qemu_fclose(comp_param[i].file); + comp_param[i].file = NULL; +@@ -519,6 +690,7 @@ static void compress_threads_save_cleanup(void) + g_free(comp_param); + compress_threads = NULL; + comp_param = NULL; ++ clean_compress_ops(); + } + + static int compress_threads_save_setup(void) +@@ -528,6 +700,12 @@ static int compress_threads_save_setup(void) + if (!migrate_use_compression()) { + return 0; + } ++ ++ if (set_compress_ops() < 0) { ++ clean_compress_ops(); ++ return -1; ++ } ++ + thread_count = migrate_compress_threads(); + compress_threads = g_new0(QemuThread, thread_count); + comp_param = g_new0(CompressParam, thread_count); +@@ -539,8 +717,7 @@ static int compress_threads_save_setup(void) + goto exit; + } + +- if (deflateInit(&comp_param[i].stream, +- migrate_compress_level()) != Z_OK) { ++ if (compress_ops->save_setup(&comp_param[i]) < 0) { + g_free(comp_param[i].originbuf); + goto exit; + } +@@ -1338,50 +1515,6 @@ static int ram_save_multifd_page(RAMState *rs, RAMBlock *block, + return 1; + } + +-/* +- * Compress size bytes of data start at p and store the compressed +- * data to the buffer of f. +- * +- * Since the file is dummy file with empty_ops, return -1 if f has no space to +- * save the compressed data. +- */ +-static ssize_t qemu_put_compression_data(CompressParam *param, size_t size) +-{ +- int err; +- uint8_t *dest = NULL; +- z_stream *stream = ¶m->stream; +- uint8_t *p = param->originbuf; +- QEMUFile *f = f = param->file; +- ssize_t blen = qemu_put_compress_start(f, &dest); +- +- if (blen < compressBound(size)) { +- return -1; +- } +- +- err = deflateReset(stream); +- if (err != Z_OK) { +- return -1; +- } +- +- stream->avail_in = size; +- stream->next_in = p; +- stream->avail_out = blen; +- stream->next_out = dest; +- +- err = deflate(stream, Z_FINISH); +- if (err != Z_STREAM_END) { +- return -1; +- } +- +- blen = stream->next_out - dest; +- if (blen < 0) { +- return -1; +- } +- +- qemu_put_compress_end(f, blen); +- return blen + sizeof(int32_t); +-} +- + static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) + { + RAMState *rs = ram_state; +@@ -1404,7 +1537,7 @@ static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) + * decompression + */ + memcpy(param->originbuf, p, TARGET_PAGE_SIZE); +- ret = qemu_put_compression_data(param, TARGET_PAGE_SIZE); ++ ret = compress_ops->compress_data(param, TARGET_PAGE_SIZE); + if (ret < 0) { + qemu_file_set_error(migrate_get_current()->to_dst_file, ret); + error_report("compressed data failed!"); +@@ -3413,32 +3546,6 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) + } + } + +-/* return the size after decompression, or negative value on error */ +-static int +-qemu_uncompress_data(DecompressParam *param, uint8_t *dest, size_t pagesize) +-{ +- int err; +- +- z_stream *stream = ¶m->stream; +- +- err = inflateReset(stream); +- if (err != Z_OK) { +- return -1; +- } +- +- stream->avail_in = param->len; +- stream->next_in = param->compbuf; +- stream->avail_out = pagesize; +- 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; +@@ -3452,7 +3559,7 @@ static void *do_data_decompress(void *opaque) + param->des = 0; + qemu_mutex_unlock(¶m->mutex); + +- ret = qemu_uncompress_data(param, des, TARGET_PAGE_SIZE); ++ ret = decompress_ops->decompress_data(param, des, TARGET_PAGE_SIZE); + if (ret < 0 && migrate_get_current()->decompress_error_check) { + error_report("decompress data failed"); + qemu_file_set_error(decomp_file, ret); +@@ -3522,7 +3629,7 @@ static void compress_threads_load_cleanup(void) + 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); ++ decompress_ops->load_cleanup(&decomp_param[i]); + g_free(decomp_param[i].compbuf); + decomp_param[i].compbuf = NULL; + } +@@ -3531,6 +3638,7 @@ static void compress_threads_load_cleanup(void) + decompress_threads = NULL; + decomp_param = NULL; + decomp_file = NULL; ++ clean_decompress_ops(); + } + + static int compress_threads_load_setup(QEMUFile *f) +@@ -3541,6 +3649,11 @@ static int compress_threads_load_setup(QEMUFile *f) + return 0; + } + ++ if (set_decompress_ops() < 0) { ++ clean_decompress_ops(); ++ return -1; ++ } ++ + thread_count = migrate_decompress_threads(); + decompress_threads = g_new0(QemuThread, thread_count); + decomp_param = g_new0(DecompressParam, thread_count); +@@ -3548,7 +3661,7 @@ static int compress_threads_load_setup(QEMUFile *f) + qemu_cond_init(&decomp_done_cond); + decomp_file = f; + for (i = 0; i < thread_count; i++) { +- if (inflateInit(&decomp_param[i].stream) != Z_OK) { ++ if (decompress_ops->load_setup(&decomp_param[i]) < 0) { + goto exit; + } + +@@ -4156,7 +4269,7 @@ static int ram_load_precopy(QEMUFile *f) + + case RAM_SAVE_FLAG_COMPRESS_PAGE: + len = qemu_get_be32(f); +- if (len < 0 || len > compressBound(TARGET_PAGE_SIZE)) { ++ if (decompress_ops->check_len(len)) { + error_report("Invalid compressed data length: %d", len); + ret = -EINVAL; + break; +-- +2.27.0 + diff --git a/migration-Add-zstd-support-in-multi-thread-compressi.patch b/migration-Add-zstd-support-in-multi-thread-compressi.patch new file mode 100644 index 0000000000000000000000000000000000000000..26d665a891a02a8758a3b2418048701e5f189cc3 --- /dev/null +++ b/migration-Add-zstd-support-in-multi-thread-compressi.patch @@ -0,0 +1,239 @@ +From bafba05f7405ba31213120d99679cc4b6c1be68e Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 16:15:10 +0800 +Subject: [PATCH] migration: Add zstd support in multi-thread compression + +This patch enables zstd option in multi-thread compression. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + hw/core/qdev-properties-system.c | 2 +- + migration/ram.c | 131 ++++++++++++++++++++++++++++++- + qapi/migration.json | 3 +- + 3 files changed, 132 insertions(+), 4 deletions(-) + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index 8c265bed6f..6a6ff03be7 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -1124,7 +1124,7 @@ const PropertyInfo qdev_prop_uuid = { + const PropertyInfo qdev_prop_compress_method = { + .name = "CompressMethod", + .description = "multi-thread compression method, " +- "zlib", ++ "zlib/zstd", + .enum_table = &CompressMethod_lookup, + .get = qdev_propinfo_get_enum, + .set = qdev_propinfo_set_enum, +diff --git a/migration/ram.c b/migration/ram.c +index 069560e7f9..c3484ee1a9 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -62,6 +62,11 @@ + #include "qemu/userfaultfd.h" + #endif /* defined(__linux__) */ + ++#ifdef CONFIG_ZSTD ++#include ++#include ++#endif ++ + /***********************************************************/ + /* ram save/restore */ + +@@ -415,11 +420,16 @@ struct CompressParam { + ram_addr_t offset; + + /* internally used fields */ +- z_stream stream; + uint8_t *originbuf; + + /* for zlib compression */ + z_stream stream; ++ ++#ifdef CONFIG_ZSTD ++ ZSTD_CStream *zstd_cs; ++ ZSTD_inBuffer in; ++ ZSTD_outBuffer out; ++#endif + }; + typedef struct CompressParam CompressParam; + +@@ -434,6 +444,11 @@ struct DecompressParam { + + /* for zlib compression */ + z_stream stream; ++#ifdef CONFIG_ZSTD ++ ZSTD_DStream *zstd_ds; ++ ZSTD_inBuffer in; ++ ZSTD_outBuffer out; ++#endif + }; + typedef struct DecompressParam DecompressParam; + +@@ -482,7 +497,7 @@ static int zlib_save_setup(CompressParam *param) + } + + static ssize_t zlib_compress_data(CompressParam *param, size_t size) +- ++{ + int err; + uint8_t *dest = NULL; + z_stream *stream = ¶m->stream; +@@ -567,6 +582,103 @@ static int zlib_check_len(int len) + return len < 0 || len > compressBound(TARGET_PAGE_SIZE); + } + ++#ifdef CONFIG_ZSTD ++static int zstd_save_setup(CompressParam *param) ++{ ++ int res; ++ param->zstd_cs = ZSTD_createCStream(); ++ if (!param->zstd_cs) { ++ return -1; ++ } ++ res = ZSTD_initCStream(param->zstd_cs, migrate_compress_level()); ++ if (ZSTD_isError(res)) { ++ return -1; ++ } ++ return 0; ++} ++static void zstd_save_cleanup(CompressParam *param) ++{ ++ ZSTD_freeCStream(param->zstd_cs); ++ param->zstd_cs = NULL; ++} ++static ssize_t zstd_compress_data(CompressParam *param, size_t size) ++{ ++ int ret; ++ uint8_t *dest = NULL; ++ uint8_t *p = param->originbuf; ++ QEMUFile *f = f = param->file; ++ ssize_t blen = qemu_put_compress_start(f, &dest); ++ if (blen < ZSTD_compressBound(size)) { ++ return -1; ++ } ++ param->out.dst = dest; ++ param->out.size = blen; ++ param->out.pos = 0; ++ param->in.src = p; ++ param->in.size = size; ++ param->in.pos = 0; ++ do { ++ ret = ZSTD_compressStream2(param->zstd_cs, ¶m->out, ++ ¶m->in, ZSTD_e_end); ++ } while (ret > 0 && (param->in.size - param->in.pos > 0) ++ && (param->out.size - param->out.pos > 0)); ++ if (ret > 0 && (param->in.size - param->in.pos > 0)) { ++ return -1; ++ } ++ if (ZSTD_isError(ret)) { ++ return -1; ++ } ++ blen = param->out.pos; ++ qemu_put_compress_end(f, blen); ++ return blen + sizeof(int32_t); ++} ++ ++static int zstd_load_setup(DecompressParam *param) ++{ ++ int ret; ++ param->zstd_ds = ZSTD_createDStream(); ++ if (!param->zstd_ds) { ++ return -1; ++ } ++ ret = ZSTD_initDStream(param->zstd_ds); ++ if (ZSTD_isError(ret)) { ++ return -1; ++ } ++ return 0; ++} ++static void zstd_load_cleanup(DecompressParam *param) ++{ ++ ZSTD_freeDStream(param->zstd_ds); ++ param->zstd_ds = NULL; ++} ++static int ++zstd_decompress_data(DecompressParam *param, uint8_t *dest, size_t size) ++{ ++ int ret; ++ param->out.dst = dest; ++ param->out.size = size; ++ param->out.pos = 0; ++ param->in.src = param->compbuf; ++ param->in.size = param->len; ++ param->in.pos = 0; ++ do { ++ ret = ZSTD_decompressStream(param->zstd_ds, ¶m->out, ¶m->in); ++ } while (ret > 0 && (param->in.size - param->in.pos > 0) ++ && (param->out.size - param->out.pos > 0)); ++ if (ret > 0 && (param->in.size - param->in.pos > 0)) { ++ return -1; ++ } ++ if (ZSTD_isError(ret)) { ++ return -1; ++ } ++ return ret; ++} ++static int zstd_check_len(int len) ++{ ++ return len < 0 || len > ZSTD_compressBound(TARGET_PAGE_SIZE); ++} ++#endif ++ + static int set_compress_ops(void) + { + compress_ops = g_new0(MigrationCompressOps, 1); +@@ -577,6 +689,13 @@ static int set_compress_ops(void) + compress_ops->save_cleanup = zlib_save_cleanup; + compress_ops->compress_data = zlib_compress_data; + break; ++#ifdef CONFIG_ZSTD ++ case COMPRESS_METHOD_ZSTD: ++ compress_ops->save_setup = zstd_save_setup; ++ compress_ops->save_cleanup = zstd_save_cleanup; ++ compress_ops->compress_data = zstd_compress_data; ++ break; ++#endif + default: + return -1; + } +@@ -595,6 +714,14 @@ static int set_decompress_ops(void) + decompress_ops->decompress_data = zlib_decompress_data; + decompress_ops->check_len = zlib_check_len; + break; ++#ifdef CONFIG_ZSTD ++ case COMPRESS_METHOD_ZSTD: ++ decompress_ops->load_setup = zstd_load_setup; ++ decompress_ops->load_cleanup = zstd_load_cleanup; ++ decompress_ops->decompress_data = zstd_decompress_data; ++ decompress_ops->check_len = zstd_check_len; ++ break; ++#endif + default: + return -1; + } +diff --git a/qapi/migration.json b/qapi/migration.json +index 3a76907ea9..d4ebc5f028 100644 +--- a/qapi/migration.json ++++ b/qapi/migration.json +@@ -602,12 +602,13 @@ + # An enumeration of multi-thread compression methods. + # + # @zlib: use zlib compression method. ++# @zstd: use zstd compression method. + # + # Since: 5.0 + # + ## + { 'enum': 'CompressMethod', +- 'data': [ 'zlib' ] } ++ 'data': [ 'zlib', { 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] } + + ## + # @MigrationParameter: +-- +2.27.0 + diff --git a/migration-Refactoring-multi-thread-compress-migratio.patch b/migration-Refactoring-multi-thread-compress-migratio.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f98b3acfeb3382ec0580c2e78deb8440ba7216a --- /dev/null +++ b/migration-Refactoring-multi-thread-compress-migratio.patch @@ -0,0 +1,289 @@ +From b871594aa1798ddcc7f5124e5b3e1c5d858c155c Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 15:21:17 +0800 +Subject: [PATCH] migration: Refactoring multi-thread compress migration + +Code refactor for the compression procedure which includes: + +1. Move qemu_compress_data and qemu_put_compression_data from qemu-file.c to +ram.c, for the reason that most part of the code logical has nothing to do +with qemu-file. Besides, the decompression code is located at ram.c only. + +2. Simplify the function input arguments for compression and decompression. +Wrap the input into the param structure which already exists. This change also +makes the function much more flexible for other compression methods. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + migration/qemu-file.c | 61 ++++++------------------------- + migration/qemu-file.h | 4 +- + migration/ram.c | 85 +++++++++++++++++++++++++++++++------------ + 3 files changed, 75 insertions(+), 75 deletions(-) + +diff --git a/migration/qemu-file.c b/migration/qemu-file.c +index 6338d8e2ff..e07026da4f 100644 +--- a/migration/qemu-file.c ++++ b/migration/qemu-file.c +@@ -745,55 +745,6 @@ uint64_t qemu_get_be64(QEMUFile *f) + return v; + } + +-/* return the size after compression, or negative value on error */ +-static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len, +- const uint8_t *source, size_t source_len) +-{ +- int err; +- +- err = deflateReset(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 = deflate(stream, Z_FINISH); +- if (err != Z_STREAM_END) { +- return -1; +- } +- +- return stream->next_out - dest; +-} +- +-/* Compress size bytes of data start at p and store the compressed +- * data to the buffer of f. +- * +- * Since the file is dummy file with empty_ops, return -1 if f has no space to +- * save the compressed data. +- */ +-ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, +- const uint8_t *p, size_t size) +-{ +- ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t); +- +- if (blen < compressBound(size)) { +- return -1; +- } +- +- blen = qemu_compress_data(stream, f->buf + f->buf_index + sizeof(int32_t), +- blen, p, size); +- if (blen < 0) { +- return -1; +- } +- +- qemu_put_be32(f, blen); +- add_buf_to_iovec(f, blen); +- return blen + sizeof(int32_t); +-} + + /* Put the data in the buffer of f_src to the buffer of f_des, and + * then reset the buf_index of f_src to 0. +@@ -866,3 +817,15 @@ QIOChannel *qemu_file_get_ioc(QEMUFile *file) + { + return file->has_ioc ? QIO_CHANNEL(file->opaque) : NULL; + } ++ ++ssize_t qemu_put_compress_start(QEMUFile *f, uint8_t **dest_ptr) ++{ ++ *dest_ptr = f->buf + f->buf_index + sizeof(int32_t); ++ return IO_BUF_SIZE - f->buf_index - sizeof(int32_t); ++} ++ ++void qemu_put_compress_end(QEMUFile *f, unsigned int v) ++{ ++ qemu_put_be32(f, v); ++ add_buf_to_iovec(f, v); ++} +diff --git a/migration/qemu-file.h b/migration/qemu-file.h +index 3f36d4dc8c..617a1373ad 100644 +--- a/migration/qemu-file.h ++++ b/migration/qemu-file.h +@@ -139,8 +139,6 @@ bool qemu_file_is_writable(QEMUFile *f); + + size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset); + size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size); +-ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, +- const uint8_t *p, size_t size); + int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src); + + /* +@@ -167,6 +165,8 @@ void ram_control_before_iterate(QEMUFile *f, uint64_t flags); + void ram_control_after_iterate(QEMUFile *f, uint64_t flags); + void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data); + ++ssize_t qemu_put_compress_start(QEMUFile *f, uint8_t **dest_ptr); ++void qemu_put_compress_end(QEMUFile *f, unsigned int v); + /* Whenever this is found in the data stream, the flags + * will be passed to ram_control_load_hook in the incoming-migration + * side. This lets before_ram_iterate/after_ram_iterate add +diff --git a/migration/ram.c b/migration/ram.c +index 863035d235..1176816fba 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -449,26 +449,22 @@ static QemuThread *decompress_threads; + static QemuMutex decomp_done_lock; + static QemuCond decomp_done_cond; + +-static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, +- ram_addr_t offset, uint8_t *source_buf); ++static bool do_compress_ram_page(CompressParam *param, RAMBlock *block); + + static void *do_data_compress(void *opaque) + { + CompressParam *param = opaque; + RAMBlock *block; +- ram_addr_t offset; + bool zero_page; + + qemu_mutex_lock(¶m->mutex); + while (!param->quit) { + if (param->block) { + block = param->block; +- offset = param->offset; + param->block = NULL; + qemu_mutex_unlock(¶m->mutex); + +- zero_page = do_compress_ram_page(param->file, ¶m->stream, +- block, offset, param->originbuf); ++ zero_page = do_compress_ram_page(param, block); + + qemu_mutex_lock(&comp_done_lock); + param->done = true; +@@ -1342,28 +1338,73 @@ static int ram_save_multifd_page(RAMState *rs, RAMBlock *block, + return 1; + } + +-static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, +- ram_addr_t offset, uint8_t *source_buf) ++/* ++ * Compress size bytes of data start at p and store the compressed ++ * data to the buffer of f. ++ * ++ * Since the file is dummy file with empty_ops, return -1 if f has no space to ++ * save the compressed data. ++ */ ++static ssize_t qemu_put_compression_data(CompressParam *param, size_t size) ++{ ++ int err; ++ uint8_t *dest = NULL; ++ z_stream *stream = ¶m->stream; ++ uint8_t *p = param->originbuf; ++ QEMUFile *f = f = param->file; ++ ssize_t blen = qemu_put_compress_start(f, &dest); ++ ++ if (blen < compressBound(size)) { ++ return -1; ++ } ++ ++ err = deflateReset(stream); ++ if (err != Z_OK) { ++ return -1; ++ } ++ ++ stream->avail_in = size; ++ stream->next_in = p; ++ stream->avail_out = blen; ++ stream->next_out = dest; ++ ++ err = deflate(stream, Z_FINISH); ++ if (err != Z_STREAM_END) { ++ return -1; ++ } ++ ++ blen = stream->next_out - dest; ++ if (blen < 0) { ++ return -1; ++ } ++ ++ qemu_put_compress_end(f, blen); ++ return blen + sizeof(int32_t); ++} ++ ++static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) + { + RAMState *rs = ram_state; ++ ram_addr_t offset = param->offset; + uint8_t *p = block->host + (offset & TARGET_PAGE_MASK); + bool zero_page = false; + int ret; + +- if (save_zero_page_to_file(rs, f, block, offset)) { ++ if (save_zero_page_to_file(rs, param->file, block, offset)) { + zero_page = true; + goto exit; + } + +- save_page_header(rs, f, block, offset | RAM_SAVE_FLAG_COMPRESS_PAGE); ++ save_page_header(rs, param->file, block, ++ offset | RAM_SAVE_FLAG_COMPRESS_PAGE); + + /* + * 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, TARGET_PAGE_SIZE); +- ret = qemu_put_compression_data(f, stream, source_buf, TARGET_PAGE_SIZE); ++ memcpy(param->originbuf, p, TARGET_PAGE_SIZE); ++ ret = qemu_put_compression_data(param, TARGET_PAGE_SIZE); + if (ret < 0) { + qemu_file_set_error(migrate_get_current()->to_dst_file, ret); + error_report("compressed data failed!"); +@@ -3374,19 +3415,20 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) + + /* 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) ++qemu_uncompress_data(DecompressParam *param, uint8_t *dest, size_t pagesize) + { + int err; + ++ z_stream *stream = ¶m->stream; ++ + 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->avail_in = param->len; ++ stream->next_in = param->compbuf; ++ stream->avail_out = pagesize; + stream->next_out = dest; + + err = inflate(stream, Z_NO_FLUSH); +@@ -3400,22 +3442,17 @@ qemu_uncompress_data(z_stream *stream, uint8_t *dest, size_t dest_len, + static void *do_data_decompress(void *opaque) + { + DecompressParam *param = opaque; +- unsigned long pagesize; + uint8_t *des; +- int len, ret; ++ int 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 = TARGET_PAGE_SIZE; +- +- ret = qemu_uncompress_data(¶m->stream, des, pagesize, +- param->compbuf, len); ++ ret = qemu_uncompress_data(param, des, TARGET_PAGE_SIZE); + if (ret < 0 && migrate_get_current()->decompress_error_check) { + error_report("decompress data failed"); + qemu_file_set_error(decomp_file, ret); +-- +2.27.0 + diff --git a/qapi-block-core-Add-retry-option-for-error-action.patch b/qapi-block-core-Add-retry-option-for-error-action.patch new file mode 100644 index 0000000000000000000000000000000000000000..521b2acb488ea650bd333192f355539a8ed5f6f6 --- /dev/null +++ b/qapi-block-core-Add-retry-option-for-error-action.patch @@ -0,0 +1,53 @@ +From 4c3d47e04886e072acc0e4fefdc49e9d1f6b4ad1 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:45 +0800 +Subject: [PATCH] qapi/block-core: Add retry option for error action + +Add a new error action 'retry' to support retry on errors. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + blockdev.c | 2 ++ + qapi/block-core.json | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/blockdev.c b/blockdev.c +index b35072644e..6f1981635b 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -333,6 +333,8 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp) + return BLOCKDEV_ON_ERROR_STOP; + } else if (!strcmp(buf, "report")) { + return BLOCKDEV_ON_ERROR_REPORT; ++ } else if (!strcmp(buf, "retry")) { ++ return BLOCKDEV_ON_ERROR_RETRY; + } else { + error_setg(errp, "'%s' invalid %s error action", + buf, is_read ? "read" : "write"); +diff --git a/qapi/block-core.json b/qapi/block-core.json +index 1d3dd9cb48..804beabfb0 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -1146,7 +1146,7 @@ + # Since: 1.3 + ## + { 'enum': 'BlockdevOnError', +- 'data': ['report', 'ignore', 'enospc', 'stop', 'auto'] } ++ 'data': ['report', 'ignore', 'enospc', 'stop', 'auto', 'retry'] } + + ## + # @MirrorSyncMode: +@@ -4952,7 +4952,7 @@ + # Since: 2.1 + ## + { 'enum': 'BlockErrorAction', +- 'data': [ 'ignore', 'report', 'stop' ] } ++ 'data': [ 'ignore', 'report', 'stop', 'retry' ] } + + + ## +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index 4efe98fbd9889c5f666a1c2946cd9d45e9c3d92d..9211d5225737e51deb173b176669fe26c9f9090d 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,455 +1,951 @@ Name: qemu +Patch0002: cpu-add-Kunpeng-920-cpu-support.patch +Patch0003: cpu-add-Cortex-A72-processor-kvm-target-support.patch +Patch0004: add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch Version: 6.2.0 -Release: 1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Release: 2 +Patch0001: cpu-parse-feature-to-avoid-failure.patch Epoch: 2 +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU is a generic and open source machine emulator and virtualizer +Patch0001: cpu-parse-feature-to-avoid-failure.patch License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 +Patch0001: cpu-parse-feature-to-avoid-failure.patch URL: http://www.qemu.org +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source0: https://www.qemu.org/download/%{name}-%{version}%{?rcstr}.tar.xz +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source1: 80-kvm.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source2: 99-qemu-guest-agent.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source3: bridge.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: flex +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gcc +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: bison +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: texinfo +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: perl-podlators +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: kernel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: chrpath +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gettext +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: python-sphinx +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: ninja-build +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: zlib-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: zstd-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gtk3-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gnutls-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: numactl-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: device-mapper-multipath-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: rdma-core-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libcap-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libcap-ng-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: cyrus-sasl-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libaio-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: usbredir-devel >= 0.5.2 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libseccomp-devel >= 2.3.0 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: systemd-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libiscsi-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: snappy-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: lzo-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: ncurses-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libattr-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libcurl-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libjpeg-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libpng-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: brlapi-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: pixman-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libusbx-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: bzip2-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libepoxy-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libtasn1-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libxml2-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libudev-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: pam-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: perl-Test-Harness +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: python3-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: librbd-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: krb5-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libssh-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: glib2 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: spice-server-devel >= 0.12.5 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: spice-protocol >= 0.12.3 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libfdt-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: virglrenderer-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): /usr/bin/getent +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): /usr/sbin/groupadd +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): /usr/sbin/useradd +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(preun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): qemu-block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): qemu-block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description +Patch0001: cpu-parse-feature-to-avoid-failure.patch QEMU is a FAST! processor emulator using dynamic translation to achieve good emulation speed. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch QEMU has two operating modes: +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch Full system emulation. In this mode, QEMU emulates a full system (for example a PC), +Patch0001: cpu-parse-feature-to-avoid-failure.patch including one or several processors and various peripherals. It can be used to launch +Patch0001: cpu-parse-feature-to-avoid-failure.patch different Operating Systems without rebooting the PC or to debug system code. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch User mode emulation. In this mode, QEMU can launch processes compiled for one CPU on another CPU. +Patch0001: cpu-parse-feature-to-avoid-failure.patch It can be used to launch the Wine Windows API emulator (https://www.winehq.org) or to ease +Patch0001: cpu-parse-feature-to-avoid-failure.patch cross-compilation and cross-debugging. +Patch0001: cpu-parse-feature-to-avoid-failure.patch You can refer to https://www.qemu.org for more infortmation. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU guest agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(preun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides an agent to run inside guests, which communicates +Patch0001: cpu-parse-feature-to-avoid-failure.patch with the host over a virtio-serial channel named "org.qemu.guest_agent.0" +Patch0001: cpu-parse-feature-to-avoid-failure.patch Please refer to https://wiki.qemu.org/Features/GuestAgent for more information. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package help +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Documents for qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch Buildarch: noarch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description help +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides documents for qemu related man help and information. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package img +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU command line tool for manipulating disk images +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description img +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides a command line tool for manipulating disk images +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides RBD support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides block-ssh support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides block-iscsi support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides block-curl support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch %{ix86} x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package include bios-256k.bin and bios.bin of seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %prep +Patch0001: cpu-parse-feature-to-avoid-failure.patch %setup -q -n qemu-%{version}%{?rcstr} +Patch0001: cpu-parse-feature-to-avoid-failure.patch %autopatch -p1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %build +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch buildarch="x86_64-softmmu" +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch buildarch="aarch64-softmmu" +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch buildldflags="VL_LDFLAGS=-Wl,--build-id" +Patch0001: cpu-parse-feature-to-avoid-failure.patch qemubuilddir="build" +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch ./configure \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --prefix=%{_prefix} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --target-list=${buildarch} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --extra-cflags="%{optflags} -fPIE -DPIE -fPIC" \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --extra-ldflags="-Wl,--build-id -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack" \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --datadir=%{_datadir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --docdir=%{_docdir}/ \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --libdir=%{_libdir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --libexecdir=%{_libexecdir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --localstatedir=%{_localstatedir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --sysconfdir=%{_sysconfdir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --interp-prefix=%{_prefix}/qemu-%%M \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --firmwarepath=%{_datadir}/%{name} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --with-pkgversion=%{name}-%{version}-%{release} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --python=/usr/bin/python3 \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-slirp \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-gtk \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-docs \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-guest-agent \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-pie \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-numa \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-mpath \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-libnfs \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-bzip2 \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-kvm \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-tcg \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-rdma \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-linux-aio \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-cap-ng \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-vhost-user \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-tpm \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-modules \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-libssh \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-spice \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-fdt \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-virglrenderer \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-cap-ng \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-libusb \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-dmg \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-qcow1 \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-vdi \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-vvfat \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-qed \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-parallels \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-capstone \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-smartcard \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-zstd \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-plugins +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch make %{?_smp_mflags} $buildldflags V=1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch cp ${qemubuilddir}/${buildarch}/qemu-system-* qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %install +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch make %{?_smp_mflags} DESTDIR=%{buildroot} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch install +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %find_lang %{name} +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -m 0755 qemu-kvm %{buildroot}%{_libexecdir}/ +Patch0001: cpu-parse-feature-to-avoid-failure.patch ln -s %{_libexecdir}/qemu-kvm %{buildroot}/%{_bindir}/qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm %{buildroot}/%{_bindir}/qemu-system-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 contrib/systemd/qemu-pr-helper.service %{buildroot}%{_unitdir}/qemu-pr-helper.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 contrib/systemd/qemu-pr-helper.socket %{buildroot}%{_unitdir}/qemu-pr-helper.socket +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 qemu.sasl %{buildroot}%{_sysconfdir}/sasl2/qemu.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -m 0644 %{_sourcedir}/bridge.conf %{buildroot}%{_sysconfdir}/qemu/bridge.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -m 0644 %{_sourcedir}/80-kvm.rules %{buildroot}/usr/lib/udev/rules.d/80-kvm.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch # For qemu-guest-agent package +Patch0001: cpu-parse-feature-to-avoid-failure.patch %global _udevdir /lib/udev/rules.d +Patch0001: cpu-parse-feature-to-avoid-failure.patch +- cpu: parse +/- feature to avoid failure +- cpu: add Kunpeng-920 cpu support +- cpu: add Cortex-A72 processor kvm target support +- add Phytium's CPU models: FT-2000+ and Tengyun-S2500. + install -D -p -m 0644 contrib/systemd/qemu-guest-agent.service %{buildroot}%{_unitdir}/qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -m 0644 %{_sourcedir}/99-qemu-guest-agent.rules %{buildroot}%{_udevdir}/99-qemu-guest-agent.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch mkdir -p %{buildroot}%{_localstatedir}/log +Patch0001: cpu-parse-feature-to-avoid-failure.patch touch %{buildroot}%{_localstatedir}/log/qga-fsfreeze-hook.log +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch # For qemu docs package +Patch0001: cpu-parse-feature-to-avoid-failure.patch %global qemudocdir %{_docdir}/%{name} +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/specs +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/.buildinfo +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/objects.inv +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/genindex.html +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/index.html +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 -t %{buildroot}%{qemudocdir} README.rst COPYING COPYING.LIB LICENSE +Patch0001: cpu-parse-feature-to-avoid-failure.patch chmod -x %{buildroot}%{_mandir}/man1/* +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vgabios*bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/bios*.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/linuxboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/kvmvapic.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/sgabios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/multiboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/linuxboot_dma.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/pvh.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vgabios-ati.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/bios-microvm.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/multiboot_dma.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/npcm7xx_bootrom.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/openbios-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/slof.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/QEMU,*.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/bamboo.dtb +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/canyonlands.dtb +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware.img +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/palcode-clipper +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/petalogix-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/ppc_* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/qemu_vga.ndrv +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/s390-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/skiboot.lid +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/spapr-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/u-boot* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_bindir}/ivshmem* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -f %{buildroot}%{_datadir}/%{name}/edk2* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/firmware +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/opensbi* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/qemu-nsis.bmp +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/audio-oss.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/audio-pa.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/block-gluster.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-curses.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-gtk.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-sdl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/audio-spice.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/chardev-baum.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/chardev-spice.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-display-qxl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-usb-host.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-usb-redirect.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-opengl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-app.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-core.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libexecdir}/vhost-user-gpu +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vhost-user/50-qemu-gpu.json +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vhost-user/50-qemu-virtiofsd.json +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-rbd.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-iscsi.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-curl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-ssh.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch for f in %{buildroot}%{_bindir}/* %{buildroot}%{_libdir}/* \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{buildroot}%{_libexecdir}/*; do +Patch0001: cpu-parse-feature-to-avoid-failure.patch if file $f | grep -q ELF | grep -q -i shared; then chrpath --delete $f; fi +Patch0001: cpu-parse-feature-to-avoid-failure.patch done +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %check +Patch0001: cpu-parse-feature-to-avoid-failure.patch make check V=1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %pre +Patch0001: cpu-parse-feature-to-avoid-failure.patch getent group kvm >/dev/null || groupadd -g 36 -r kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch getent group qemu >/dev/null || groupadd -g 107 -r qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch getent passwd qemu >/dev/null || \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch -c "qemu user" qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %post guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %systemd_post qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %preun guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %systemd_preun qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %postun guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %systemd_postun_with_restart qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files -f %{name}.lang +Patch0001: cpu-parse-feature-to-avoid-failure.patch %dir %{_datadir}/%{name}/ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libexecdir}/qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/accel-qtest-*.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/accel-tcg-*.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-vga-gl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-vga.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu-gl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu-pci-gl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu-pci.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-virtio.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-e1000.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-e1000e.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-rtl8139.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-pcnet.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-ne2k_pci.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-eepro100.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-vmxnet3.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-virtio.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-e1000.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-ne2k_pci.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-pcnet.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-rtl8139.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-eepro100.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/qboot.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/trace-events-all +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/applications/qemu.desktop +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/icons/hicolor/*/apps/* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/keymaps/ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/elf2dmp +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-edid +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-keymap +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-pr-helper +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libexecdir}/virtfs-proxy-helper +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libexecdir}/virtiofsd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_unitdir}/qemu-pr-helper.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_unitdir}/qemu-pr-helper.socket +Patch0001: cpu-parse-feature-to-avoid-failure.patch %attr(4755, root, root) %{_libexecdir}/qemu-bridge-helper +Patch0001: cpu-parse-feature-to-avoid-failure.patch %config(noreplace) %{_sysconfdir}/sasl2/qemu.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch %dir %{_sysconfdir}/qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch %config(noreplace) %{_sysconfdir}/qemu/bridge.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch /usr/lib/udev/rules.d/80-kvm.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/COPYING +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/COPYING.LIB +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/LICENSE +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios-256k.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-cirrus.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-qxl.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-stdvga.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-vmware.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-virtio.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-ramfb.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-bochs-display.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/linuxboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/linuxboot_dma.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pvh.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/multiboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/kvmvapic.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/sgabios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files help +Patch0001: cpu-parse-feature-to-avoid-failure.patch %dir %{qemudocdir} +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/about +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/interop +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/search* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/_static +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/system +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/tools +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/user +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/README.rst +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/qemu.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/qemu-img.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/qemu-storage-daemon.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/virtfs-proxy-helper.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/virtiofsd.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-block-drivers.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-cpu-models.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-ga-ref.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-qmp-ref.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-storage-daemon-qmp-ref.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-ga.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-nbd.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-pr-helper.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %defattr(-,root,root,-) +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-ga +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-ga.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_unitdir}/qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_udevdir}/99-qemu-guest-agent.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ghost %{_localstatedir}/log/qga-fsfreeze-hook.log +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files img +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-img +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-io +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-nbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-storage-daemon +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-rbd.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-ssh.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-iscsi.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-curl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch %{ix86} x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios-256k.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %changelog +* Wed Feb 09 2022 Chen Qun +- qapi/block-core: Add retry option for error action +- block-backend: Introduce retry timer +- block-backend: Add device specific retry callback +- block-backend: Enable retry action on errors +- block-backend: Add timeout support for retry +- block: Add error retry param setting +- virtio_blk: Add support for retry on errors + +* Wed Feb 09 2022 Chen Qun +- vhost: cancel migration when vhost-user restarted during migraiton +- migration: Add multi-thread compress method +- migration: Refactoring multi-thread compress migration +- migration: Add multi-thread compress ops +- migration: Add zstd support in multi-thread compression +- migration: Add compress_level sanity check +- doc: Update multi-thread compression doc + +* Wed Feb 09 2022 Chen Qun +Patch0001: cpu-parse-feature-to-avoid-failure.patch * Thu Jan 27 2022 Xiangdong Liu +Patch0001: cpu-parse-feature-to-avoid-failure.patch - Package init +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0008: doc-Update-multi-thread-compression-doc.patch +Patch0007: migration-Add-compress_level-sanity-check.patch +Patch0006: migration-Add-zstd-support-in-multi-thread-compressi.patch +Patch0005: migration-Add-multi-thread-compress-ops.patch +Patch0004: migration-Refactoring-multi-thread-compress-migratio.patch +Patch0003: migration-Add-multi-thread-compress-method.patch +Patch0002: vhost-cancel-migration-when-vhost-user-restarted-dur.patch +Patch0009: virtio_blk-Add-support-for-retry-on-errors.patch +Patch0008: block-Add-error-retry-param-setting.patch +Patch0007: block-backend-Add-timeout-support-for-retry.patch +Patch0006: block-backend-Enable-retry-action-on-errors.patch +Patch0005: block-backend-Add-device-specific-retry-callback.patch +Patch0004: block-backend-Introduce-retry-timer.patch +Patch0003: qapi-block-core-Add-retry-option-for-error-action.patch diff --git a/vhost-cancel-migration-when-vhost-user-restarted-dur.patch b/vhost-cancel-migration-when-vhost-user-restarted-dur.patch new file mode 100644 index 0000000000000000000000000000000000000000..b4142d529351e09a6b3a338b78b93a8e50a8a732 --- /dev/null +++ b/vhost-cancel-migration-when-vhost-user-restarted-dur.patch @@ -0,0 +1,60 @@ +From d41206e959717f68a31da4a2d875d33035baeb9f Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Mon, 29 Jul 2019 16:22:12 +0800 +Subject: [PATCH] vhost: cancel migration when vhost-user restarted during + migraiton + +Qemu will abort when vhost-user process is restarted during migration +when vhost_log_global_start/stop is called. The reason is clear that +vhost_dev_set_log returns -1 because network connection is temporarily +lost. Let's cancel migraiton and report it to user in this abnormal +situation. + +Signed-off-by: Ying Fang +Reviewed-by: Gonglei +--- + hw/virtio/vhost.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c +index 437347ad01..dafb23c481 100644 +--- a/hw/virtio/vhost.c ++++ b/hw/virtio/vhost.c +@@ -25,6 +25,7 @@ + #include "hw/virtio/virtio-access.h" + #include "migration/blocker.h" + #include "migration/qemu-file-types.h" ++#include "migration/migration.h" + #include "sysemu/dma.h" + #include "sysemu/tcg.h" + #include "trace.h" +@@ -947,20 +948,24 @@ check_dev_state: + static void vhost_log_global_start(MemoryListener *listener) + { + int r; ++ Error *errp = NULL; + + r = vhost_migration_log(listener, true); + if (r < 0) { +- abort(); ++ error_setg(&errp, "Failed to start vhost migration log"); ++ migrate_fd_error(migrate_get_current(), errp); + } + } + + static void vhost_log_global_stop(MemoryListener *listener) + { + int r; ++ Error *errp = NULL; + + r = vhost_migration_log(listener, false); + if (r < 0) { +- abort(); ++ error_setg(&errp, "Failed to stop vhost migration log"); ++ migrate_fd_error(migrate_get_current(), errp); + } + } + +-- +2.27.0 + diff --git a/virtio_blk-Add-support-for-retry-on-errors.patch b/virtio_blk-Add-support-for-retry-on-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..054e50061225f367704d625d8ecd00806af8efe7 --- /dev/null +++ b/virtio_blk-Add-support-for-retry-on-errors.patch @@ -0,0 +1,90 @@ +From a81122e37595fe1cc9eaa2adbbfccbfdf8f988b8 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:53 +0800 +Subject: [PATCH] virtio_blk: Add support for retry on errors + +Insert failed requests into device's list for later retry and handle +queued requests to implement retry_request_cb. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + hw/block/virtio-blk.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index f139cd7cc9..c8d94a3dfb 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -108,6 +108,10 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, + block_acct_failed(blk_get_stats(s->blk), &req->acct); + } + virtio_blk_free_request(req); ++ } else if (action == BLOCK_ERROR_ACTION_RETRY) { ++ req->mr_next = NULL; ++ req->next = s->rq; ++ s->rq = req; + } + + blk_error_action(s->blk, action, is_read, error); +@@ -149,6 +153,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + block_acct_done(blk_get_stats(s->blk), &req->acct); + virtio_blk_free_request(req); +@@ -168,6 +173,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + block_acct_done(blk_get_stats(s->blk), &req->acct); + virtio_blk_free_request(req); +@@ -190,6 +196,7 @@ static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + if (is_write_zeroes) { + block_acct_done(blk_get_stats(s->blk), &req->acct); +@@ -828,12 +835,12 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) + + void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh) + { +- VirtIOBlockReq *req = s->rq; ++ VirtIOBlockReq *req; + MultiReqBuffer mrb = {}; + +- s->rq = NULL; +- + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); ++ req = s->rq; ++ s->rq = NULL; + while (req) { + VirtIOBlockReq *next = req->next; + if (virtio_blk_handle_request(req, &mrb)) { +@@ -1138,8 +1145,16 @@ static void virtio_blk_resize(void *opaque) + aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev); + } + ++static void virtio_blk_retry_request(void *opaque) ++{ ++ VirtIOBlock *s = VIRTIO_BLK(opaque); ++ ++ virtio_blk_process_queued_requests(s, false); ++} ++ + static const BlockDevOps virtio_block_ops = { + .resize_cb = virtio_blk_resize, ++ .retry_request_cb = virtio_blk_retry_request, + }; + + static void virtio_blk_device_realize(DeviceState *dev, Error **errp) +-- +2.27.0 +