From patchwork Sun May 5 16:57:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yuan1" X-Patchwork-Id: 1931831 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=RbLH6wuA; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VXw520vhpz1xnS for ; Mon, 6 May 2024 18:47:02 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3tz9-0003Qp-SF; Mon, 06 May 2024 04:46:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyt-0003B3-Om for qemu-devel@nongnu.org; Mon, 06 May 2024 04:45:55 -0400 Received: from mgamail.intel.com ([192.198.163.16]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3typ-0003R3-41 for qemu-devel@nongnu.org; Mon, 06 May 2024 04:45:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714985151; x=1746521151; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=De/+IlPKnb37/m2P8MnERuBf3g/oG5ppYQwNCBUcprA=; b=RbLH6wuAjWBfEuijeV3/MvCUtGQ1oeqoFA2VA0NwW66zWSFGsim2lb9t y2Ek4UIERGfLHIsWgRZ3A7anCBpj6+3y63wpANoJtUX/hwNhSgZAZUxL9 JOrciKkXO/JVzVZFCPB5I0mXi3RMx3Lvn8RJ2mGUj0rvYA07BWRe+VjSL RENfGvmYXBqPkTzqb340wrFgaQdCoUAW4vuM7DvxFnNZQ+Bi04G5gg1NF 8LebT7WQmN9J4g07wxOJ0usGLhk7deMO9k1seHpCbvc3piMQyPYQuEXuL QYL5ED8v1yYeqHbe6E481Tdx4oITJKFtb5CwvG9e29aGUrN5DKx8lMI/0 Q==; X-CSE-ConnectionGUID: YAMyhPmHTCyb53HMmDCeTQ== X-CSE-MsgGUID: G2OuZSGiQu6ZmhhN1VmGoQ== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="11254984" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="11254984" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 May 2024 01:45:47 -0700 X-CSE-ConnectionGUID: PSZqrI4bRGiE+C7aE2vxMA== X-CSE-MsgGUID: cs7SLmiCR96UBzMfgha3BQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="51287471" Received: from sae-gw02.sh.intel.com (HELO localhost) ([10.239.45.110]) by fmviesa002.fm.intel.com with ESMTP; 06 May 2024 01:45:46 -0700 From: Yuan Liu To: peterx@redhat.com, farosas@suse.de Cc: qemu-devel@nongnu.org, yuan1.liu@intel.com, nanhai.zou@intel.com Subject: [PATCH v6 1/7] docs/migration: add qpl compression feature Date: Mon, 6 May 2024 00:57:45 +0800 Message-Id: <20240505165751.2392198-2-yuan1.liu@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240505165751.2392198-1-yuan1.liu@intel.com> References: <20240505165751.2392198-1-yuan1.liu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.16; envelope-from=yuan1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -37 X-Spam_score: -3.8 X-Spam_bar: --- X-Spam_report: (-3.8 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.431, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org add Intel Query Processing Library (QPL) compression method introduction Signed-off-by: Yuan Liu Reviewed-by: Nanhai Zou --- docs/devel/migration/features.rst | 1 + docs/devel/migration/qpl-compression.rst | 262 +++++++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 docs/devel/migration/qpl-compression.rst diff --git a/docs/devel/migration/features.rst b/docs/devel/migration/features.rst index d5ca7b86d5..bc98b65075 100644 --- a/docs/devel/migration/features.rst +++ b/docs/devel/migration/features.rst @@ -12,3 +12,4 @@ Migration has plenty of features to support different use cases. virtio mapped-ram CPR + qpl-compression diff --git a/docs/devel/migration/qpl-compression.rst b/docs/devel/migration/qpl-compression.rst new file mode 100644 index 0000000000..13fb7a67b1 --- /dev/null +++ b/docs/devel/migration/qpl-compression.rst @@ -0,0 +1,262 @@ +=============== +QPL Compression +=============== +The Intel Query Processing Library (Intel ``QPL``) is an open-source library to +provide compression and decompression features and it is based on deflate +compression algorithm (RFC 1951). + +The ``QPL`` compression relies on Intel In-Memory Analytics Accelerator(``IAA``) +and Shared Virtual Memory(``SVM``) technology, they are new features supported +from Intel 4th Gen Intel Xeon Scalable processors, codenamed Sapphire Rapids +processor(``SPR``). + +For more ``QPL`` introduction, please refer to `QPL Introduction +`_ + +QPL Compression Framework +========================= + +:: + + +----------------+ +------------------+ + | MultiFD Thread | |accel-config tool | + +-------+--------+ +--------+---------+ + | | + | | + |compress/decompress | + +-------+--------+ | Setup IAA + | QPL library | | Resources + +-------+---+----+ | + | | | + | +-------------+-------+ + | Open IAA | + | Devices +-----+-----+ + | |idxd driver| + | +-----+-----+ + | | + | | + | +-----+-----+ + +-----------+IAA Devices| + Submit jobs +-----------+ + via enqcmd + + +QPL Build And Installation +-------------------------- + +.. code-block:: shell + + $git clone --recursive https://github.com/intel/qpl.git qpl + $mkdir qpl/build + $cd qpl/build + $cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DQPL_LIBRARY_TYPE=SHARED .. + $sudo cmake --build . --target install + +For more details about ``QPL`` installation, please refer to `QPL Installation +`_ + +IAA Device Management +--------------------- + +The number of ``IAA`` devices will vary depending on the Xeon product model. +On a ``SPR`` server, there can be a maximum of 8 ``IAA`` devices, with up to +4 devices per socket. + +By default, all ``IAA`` devices are disabled and need to be configured and +enabled by users manually. + +Check the number of devices through the following command + +.. code-block:: shell + + #lspci -d 8086:0cfe + 6a:02.0 System peripheral: Intel Corporation Device 0cfe + 6f:02.0 System peripheral: Intel Corporation Device 0cfe + 74:02.0 System peripheral: Intel Corporation Device 0cfe + 79:02.0 System peripheral: Intel Corporation Device 0cfe + e7:02.0 System peripheral: Intel Corporation Device 0cfe + ec:02.0 System peripheral: Intel Corporation Device 0cfe + f1:02.0 System peripheral: Intel Corporation Device 0cfe + f6:02.0 System peripheral: Intel Corporation Device 0cfe + +IAA Device Configuration And Enabling +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``accel-config`` tool is used to enable ``IAA`` devices and configure +``IAA`` hardware resources(work queues and engines). One ``IAA`` device +has 8 work queues and 8 processing engines, multiple engines can be assigned +to a work queue via ``group`` attribute. + +For ``accel-config`` installation, please refer to `accel-config installation +`_ + +One example of configuring and enabling an ``IAA`` device. + +.. code-block:: shell + + #accel-config config-engine iax1/engine1.0 -g 0 + #accel-config config-engine iax1/engine1.1 -g 0 + #accel-config config-engine iax1/engine1.2 -g 0 + #accel-config config-engine iax1/engine1.3 -g 0 + #accel-config config-engine iax1/engine1.4 -g 0 + #accel-config config-engine iax1/engine1.5 -g 0 + #accel-config config-engine iax1/engine1.6 -g 0 + #accel-config config-engine iax1/engine1.7 -g 0 + #accel-config config-wq iax1/wq1.0 -g 0 -s 128 -p 10 -b 1 -t 128 -m shared -y user -n app1 -d user + #accel-config enable-device iax1 + #accel-config enable-wq iax1/wq1.0 + +.. note:: + IAX is an early name for IAA + +- The ``IAA`` device index is 1, use ``ls -lh /sys/bus/dsa/devices/iax*`` + command to query the ``IAA`` device index. + +- 8 engines and 1 work queue are configured in group 0, so all compression jobs + submitted to this work queue can be processed by all engines at the same time. + +- Set work queue attributes including the work mode, work queue size and so on. + +- Enable the ``IAA1`` device and work queue 1.0 + +.. note:: + + Set work queue mode to shared mode, since ``QPL`` library only supports + shared mode + +For more detailed configuration, please refer to `IAA Configuration Samples +`_ + +IAA Unit Test +^^^^^^^^^^^^^ + +- Enabling ``IAA`` devices for Xeon platform, please refer to `IAA User Guide + `_ + +- ``IAA`` device driver is Intel Data Accelerator Driver (idxd), it is + recommended that the minimum version of Linux kernel is 5.18. + +- Add ``"intel_iommu=on,sm_on"`` parameter to kernel command line + for ``SVM`` feature enabling. + +Here is an easy way to verify ``IAA`` device driver and ``SVM`` with `iaa_test +`_ + +.. code-block:: shell + + #./test/iaa_test + [ info] alloc wq 0 shared size 128 addr 0x7f26cebe5000 batch sz 0xfffffffe xfer sz 0x80000000 + [ info] test noop: tflags 0x1 num_desc 1 + [ info] preparing descriptor for noop + [ info] Submitted all noop jobs + [ info] verifying task result for 0x16f7e20 + [ info] test with op 0 passed + + +IAA Resources Allocation For Migration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There is no ``IAA`` resource configuration parameters for migration and +``accel-config`` tool configuration cannot directly specify the ``IAA`` +resources used for migration. + +The multifd migration with ``QPL`` compression method will use all work +queues that are enabled and shared mode. + +.. note:: + + Accessing IAA resources requires ``sudo`` command or ``root`` privileges + by default. Administrators can modify the IAA device node ownership + so that Qemu can use IAA with specified user permissions. + + For example + + #chown -R Qemu /dev/iax + + +Shared Virtual Memory(SVM) Introduction +======================================= + +An ability for an accelerator I/O device to operate in the same virtual +memory space of applications on host processors. It also implies the +ability to operate from pageable memory, avoiding functional requirements +to pin memory for DMA operations. + +When using ``SVM`` technology, users do not need to reserve memory for the +``IAA`` device and perform pin memory operation. The ``IAA`` device can +directly access data using the virtual address of the process. + +For more ``SVM`` technology, please refer to +`Shared Virtual Addressing (SVA) with ENQCMD +`_ + + +How To Use QPL Compression In Migration +======================================= + +1 - Installation of ``QPL`` library and ``accel-config`` library if using IAA + +2 - Configure and enable ``IAA`` devices and work queues via ``accel-config`` + +3 - Build ``Qemu`` with ``--enable-qpl`` parameter + + E.g. configure --target-list=x86_64-softmmu --enable-kvm ``--enable-qpl`` + +4 - Enable ``QPL`` compression during migration + + Set ``migrate_set_parameter multifd-compression qpl`` when migrating, the + ``QPL`` compression does not support configuring the compression level, it + only supports one compression level. + +The Difference Between QPL And ZLIB +=================================== + +Although both ``QPL`` and ``ZLIB`` are based on the deflate compression +algorithm, and ``QPL`` can support the header and tail of ``ZLIB``, ``QPL`` +is still not fully compatible with the ``ZLIB`` compression in the migration. + +``QPL`` only supports 4K history buffer, and ``ZLIB`` is 32K by default. The +``ZLIB`` compressed data that ``QPL`` may not decompress correctly and +vice versa. + +``QPL`` does not support the ``Z_SYNC_FLUSH`` operation in ``ZLIB`` streaming +compression, current ``ZLIB`` implementation uses ``Z_SYNC_FLUSH``, so each +``multifd`` thread has a ``ZLIB`` streaming context, and all page compression +and decompression are based on this stream. ``QPL`` cannot decompress such data +and vice versa. + +The introduction for ``Z_SYNC_FLUSH``, please refer to `Zlib Manual +`_ + +The Best Practices +================== +When user enables the IAA device for ``QPL`` compression, it is recommended +to add ``-mem-prealloc`` parameter to the destination boot parameters. This +parameter can avoid the occurrence of I/O page fault and reduce the overhead +of IAA compression and decompression. + +The example of booting with ``-mem-prealloc`` parameter + +.. code-block:: shell + + $qemu-system-x86_64 --enable-kvm -cpu host --mem-prealloc ... + + +An example about I/O page fault measurement of destination without +``-mem-prealloc``, the ``svm_prq`` indicates the number of I/O page fault +occurrences and processing time. + +.. code-block:: shell + + #echo 1 > /sys/kernel/debug/iommu/intel/dmar_perf_latency + #echo 2 > /sys/kernel/debug/iommu/intel/dmar_perf_latency + #echo 3 > /sys/kernel/debug/iommu/intel/dmar_perf_latency + #echo 4 > /sys/kernel/debug/iommu/intel/dmar_perf_latency + #cat /sys/kernel/debug/iommu/intel/dmar_perf_latency + IOMMU: dmar18 Register Base Address: c87fc000 + <0.1us 0.1us-1us 1us-10us 10us-100us 100us-1ms 1ms-10ms >=10ms min(us) max(us) average(us) + inv_iotlb 0 286 123 0 0 0 0 0 1 0 + inv_devtlb 0 276 133 0 0 0 0 0 2 0 + inv_iec 0 0 0 0 0 0 0 0 0 0 + svm_prq 0 0 25206 364 395 0 0 1 556 9 + From patchwork Sun May 5 16:57:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yuan1" X-Patchwork-Id: 1931829 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=OoAUfl/d; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VXw4d14xXz1xnS for ; Mon, 6 May 2024 18:46:41 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3tz3-0003Kw-2p; Mon, 06 May 2024 04:46:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyt-0003B6-PW for qemu-devel@nongnu.org; Mon, 06 May 2024 04:45:55 -0400 Received: from mgamail.intel.com ([192.198.163.16]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyr-0003RG-2k for qemu-devel@nongnu.org; Mon, 06 May 2024 04:45:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714985153; x=1746521153; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GS1pkcl74WF/h4OJ8r86fgDEFmLH4pI9ksnjms0coSw=; b=OoAUfl/ddmUxajSuQo3fPGjJiNLH7P8mykGWnbvW/9hDmjValxYTaGBM +N1OyDaL/Csn2Xyc84/SOthi31g1XmOeSeVVHVyiCX1Or942ZGnOdXUZq BqEDqbXjtZaEQ9PP1fkENJx5fePogDR2+/gEEbgfF53BN7KUqEgI+9Sv8 5O8od8HxCtjp8W+phKeg0RH7T8CLz2WX0NO6jn0h+rQR+qIkEf5th7MD7 +l8PdOI3Qv8eQmTWdr07O+nL4/QUBytn2a6RfsbRlCkJqyrW4LejxSKiD UzmbOlaVBscvLEqihiwTYM2hUux/20e7Br8+bx9s3m40N8P204q39MwRT w==; X-CSE-ConnectionGUID: b6fes4bqQ1mE8q8jdJ0IFg== X-CSE-MsgGUID: XNHtFR29ROSDVfVqle119g== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="11254989" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="11254989" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 May 2024 01:45:50 -0700 X-CSE-ConnectionGUID: XX+s3QZoT7ezO/0h2E37Hg== X-CSE-MsgGUID: KeE2RTxAQWOfn1Rk78hpqA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="51287494" Received: from sae-gw02.sh.intel.com (HELO localhost) ([10.239.45.110]) by fmviesa002.fm.intel.com with ESMTP; 06 May 2024 01:45:48 -0700 From: Yuan Liu To: peterx@redhat.com, farosas@suse.de Cc: qemu-devel@nongnu.org, yuan1.liu@intel.com, nanhai.zou@intel.com Subject: [PATCH v6 2/7] migration/multifd: put IOV initialization into compression method Date: Mon, 6 May 2024 00:57:46 +0800 Message-Id: <20240505165751.2392198-3-yuan1.liu@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240505165751.2392198-1-yuan1.liu@intel.com> References: <20240505165751.2392198-1-yuan1.liu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.16; envelope-from=yuan1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -37 X-Spam_score: -3.8 X-Spam_bar: --- X-Spam_report: (-3.8 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.431, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Different compression methods may require different numbers of IOVs. Based on streaming compression of zlib and zstd, all pages will be compressed to a data block, so two IOVs are needed for packet header and compressed data block. Signed-off-by: Yuan Liu Reviewed-by: Nanhai Zou Reviewed-by: Fabiano Rosas Reviewed-by: Peter Xu --- migration/multifd-zlib.c | 7 +++++++ migration/multifd-zstd.c | 8 +++++++- migration/multifd.c | 22 ++++++++++++---------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/migration/multifd-zlib.c b/migration/multifd-zlib.c index 737a9645d2..2ced69487e 100644 --- a/migration/multifd-zlib.c +++ b/migration/multifd-zlib.c @@ -70,6 +70,10 @@ static int zlib_send_setup(MultiFDSendParams *p, Error **errp) goto err_free_zbuff; } p->compress_data = z; + + /* Needs 2 IOVs, one for packet header and one for compressed data */ + p->iov = g_new0(struct iovec, 2); + return 0; err_free_zbuff: @@ -101,6 +105,9 @@ static void zlib_send_cleanup(MultiFDSendParams *p, Error **errp) z->buf = NULL; g_free(p->compress_data); p->compress_data = NULL; + + g_free(p->iov); + p->iov = NULL; } /** diff --git a/migration/multifd-zstd.c b/migration/multifd-zstd.c index 256858df0a..ca17b7e310 100644 --- a/migration/multifd-zstd.c +++ b/migration/multifd-zstd.c @@ -52,7 +52,6 @@ static int zstd_send_setup(MultiFDSendParams *p, Error **errp) struct zstd_data *z = g_new0(struct zstd_data, 1); int res; - p->compress_data = z; z->zcs = ZSTD_createCStream(); if (!z->zcs) { g_free(z); @@ -77,6 +76,10 @@ static int zstd_send_setup(MultiFDSendParams *p, Error **errp) error_setg(errp, "multifd %u: out of memory for zbuff", p->id); return -1; } + p->compress_data = z; + + /* Needs 2 IOVs, one for packet header and one for compressed data */ + p->iov = g_new0(struct iovec, 2); return 0; } @@ -98,6 +101,9 @@ static void zstd_send_cleanup(MultiFDSendParams *p, Error **errp) z->zbuff = NULL; g_free(p->compress_data); p->compress_data = NULL; + + g_free(p->iov); + p->iov = NULL; } /** diff --git a/migration/multifd.c b/migration/multifd.c index f317bff077..d82885fdbb 100644 --- a/migration/multifd.c +++ b/migration/multifd.c @@ -137,6 +137,13 @@ static int nocomp_send_setup(MultiFDSendParams *p, Error **errp) p->write_flags |= QIO_CHANNEL_WRITE_FLAG_ZERO_COPY; } + if (multifd_use_packets()) { + /* We need one extra place for the packet header */ + p->iov = g_new0(struct iovec, p->page_count + 1); + } else { + p->iov = g_new0(struct iovec, p->page_count); + } + return 0; } @@ -150,6 +157,8 @@ static int nocomp_send_setup(MultiFDSendParams *p, Error **errp) */ static void nocomp_send_cleanup(MultiFDSendParams *p, Error **errp) { + g_free(p->iov); + p->iov = NULL; return; } @@ -228,6 +237,7 @@ static int nocomp_send_prepare(MultiFDSendParams *p, Error **errp) */ static int nocomp_recv_setup(MultiFDRecvParams *p, Error **errp) { + p->iov = g_new0(struct iovec, p->page_count); return 0; } @@ -240,6 +250,8 @@ static int nocomp_recv_setup(MultiFDRecvParams *p, Error **errp) */ static void nocomp_recv_cleanup(MultiFDRecvParams *p) { + g_free(p->iov); + p->iov = NULL; } /** @@ -783,8 +795,6 @@ static bool multifd_send_cleanup_channel(MultiFDSendParams *p, Error **errp) p->packet_len = 0; g_free(p->packet); p->packet = NULL; - g_free(p->iov); - p->iov = NULL; multifd_send_state->ops->send_cleanup(p, errp); return *errp == NULL; @@ -1179,11 +1189,6 @@ bool multifd_send_setup(void) p->packet = g_malloc0(p->packet_len); p->packet->magic = cpu_to_be32(MULTIFD_MAGIC); p->packet->version = cpu_to_be32(MULTIFD_VERSION); - - /* We need one extra place for the packet header */ - p->iov = g_new0(struct iovec, page_count + 1); - } else { - p->iov = g_new0(struct iovec, page_count); } p->name = g_strdup_printf("multifdsend_%d", i); p->page_size = qemu_target_page_size(); @@ -1353,8 +1358,6 @@ static void multifd_recv_cleanup_channel(MultiFDRecvParams *p) p->packet_len = 0; g_free(p->packet); p->packet = NULL; - g_free(p->iov); - p->iov = NULL; g_free(p->normal); p->normal = NULL; g_free(p->zero); @@ -1602,7 +1605,6 @@ int multifd_recv_setup(Error **errp) p->packet = g_malloc0(p->packet_len); } p->name = g_strdup_printf("multifdrecv_%d", i); - p->iov = g_new0(struct iovec, page_count); p->normal = g_new0(ram_addr_t, page_count); p->zero = g_new0(ram_addr_t, page_count); p->page_count = page_count; From patchwork Sun May 5 16:57:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yuan1" X-Patchwork-Id: 1931833 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=dCSHntw6; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VXw5K71GPz1xnS for ; Mon, 6 May 2024 18:47:17 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3tz7-0003NV-0w; Mon, 06 May 2024 04:46:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyy-0003Fi-NS for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:01 -0400 Received: from mgamail.intel.com ([198.175.65.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyt-0003RW-0F for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714985155; x=1746521155; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ChOe8gjwm6ew8GfRN6Ns/k8C5Fe3UICSPcgTGcJ/ZK0=; b=dCSHntw6z3mDG7zHfFCKO8mGPEFwWrYg9RUUX5MYpf7NonblATPLtbDp nX7NLaU6Xjnf+Onp0LVFCW41eYDxRmNqOkxzWQ0slox/DYgKThvTKklY5 UW1cEtPqfCE273lfzBK/8z3Tc9C8QDftj3qIGRVxsEV98cUuxirA/O5hJ E/TpztvQ6TraE8o4G1kTd5Ukyj14ZmoFxk5q5O8kIfGf0K/Zp4oB5L/ea GXY+EB0Da/0M6snq/euyh37RZ79mU110dg5v1CIrsvrwV+CnHRYMX8Zll aZVH+O3LpJkruyyUoh/DF95ObNr6N6GYELENDy6AOmV/+Iw5OIPA72oUW w==; X-CSE-ConnectionGUID: OAj+tArGQRSbTHNKW1ipKQ== X-CSE-MsgGUID: 1gI0Bf4zS5CV8GDXQvmCaQ== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="21875803" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="21875803" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 May 2024 01:45:53 -0700 X-CSE-ConnectionGUID: 3p9RtNymRAOCRKH8dP8AGQ== X-CSE-MsgGUID: i4RGAygPTxW9ch5ucnmpyQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28203245" Received: from sae-gw02.sh.intel.com (HELO localhost) ([10.239.45.110]) by fmviesa006.fm.intel.com with ESMTP; 06 May 2024 01:45:51 -0700 From: Yuan Liu To: peterx@redhat.com, farosas@suse.de Cc: qemu-devel@nongnu.org, yuan1.liu@intel.com, nanhai.zou@intel.com Subject: [PATCH v6 3/7] configure: add --enable-qpl build option Date: Mon, 6 May 2024 00:57:47 +0800 Message-Id: <20240505165751.2392198-4-yuan1.liu@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240505165751.2392198-1-yuan1.liu@intel.com> References: <20240505165751.2392198-1-yuan1.liu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=198.175.65.13; envelope-from=yuan1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -37 X-Spam_score: -3.8 X-Spam_bar: --- X-Spam_report: (-3.8 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.431, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org add --enable-qpl and --disable-qpl options to enable and disable the QPL compression method for multifd migration. The Query Processing Library (QPL) is an open-source library that supports data compression and decompression features. It is based on the deflate compression algorithm and use Intel In-Memory Analytics Accelerator(IAA) hardware for compression and decompression acceleration. For more live migration with IAA, please refer to the document docs/devel/migration/qpl-compression.rst Signed-off-by: Yuan Liu Reviewed-by: Nanhai Zou --- meson.build | 8 ++++++++ meson_options.txt | 2 ++ scripts/meson-buildoptions.sh | 3 +++ 3 files changed, 13 insertions(+) diff --git a/meson.build b/meson.build index 5db2dbc12e..2a8d8385fe 100644 --- a/meson.build +++ b/meson.build @@ -1204,6 +1204,12 @@ if not get_option('zstd').auto() or have_block required: get_option('zstd'), method: 'pkg-config') endif +qpl = not_found +if not get_option('qpl').auto() or have_system + qpl = dependency('qpl', version: '>=1.5.0', + required: get_option('qpl'), + method: 'pkg-config') +endif virgl = not_found have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found() @@ -2309,6 +2315,7 @@ config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) config_host_data.set('CONFIG_STATX', has_statx) config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id) config_host_data.set('CONFIG_ZSTD', zstd.found()) +config_host_data.set('CONFIG_QPL', qpl.found()) config_host_data.set('CONFIG_FUSE', fuse.found()) config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) @@ -4436,6 +4443,7 @@ summary_info += {'snappy support': snappy} summary_info += {'bzip2 support': libbzip2} summary_info += {'lzfse support': liblzfse} summary_info += {'zstd support': zstd} +summary_info += {'Query Processing Library support': qpl} summary_info += {'NUMA host support': numa} summary_info += {'capstone': capstone} summary_info += {'libpmem support': libpmem} diff --git a/meson_options.txt b/meson_options.txt index adc77bae0c..562db29ab4 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -259,6 +259,8 @@ option('xkbcommon', type : 'feature', value : 'auto', description: 'xkbcommon support') option('zstd', type : 'feature', value : 'auto', description: 'zstd compression support') +option('qpl', type : 'feature', value : 'auto', + description: 'Query Processing Library support') option('fuse', type: 'feature', value: 'auto', description: 'FUSE block device export') option('fuse_lseek', type : 'feature', value : 'auto', diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index 0a29d35fdb..26bf9e21fd 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -222,6 +222,7 @@ meson_options_help() { printf "%s\n" ' Xen PCI passthrough support' printf "%s\n" ' xkbcommon xkbcommon support' printf "%s\n" ' zstd zstd compression support' + printf "%s\n" ' qpl Query Processing Library support' } _meson_option_parse() { case $1 in @@ -562,6 +563,8 @@ _meson_option_parse() { --disable-xkbcommon) printf "%s" -Dxkbcommon=disabled ;; --enable-zstd) printf "%s" -Dzstd=enabled ;; --disable-zstd) printf "%s" -Dzstd=disabled ;; + --enable-qpl) printf "%s" -Dqpl=enabled ;; + --disable-qpl) printf "%s" -Dqpl=disabled ;; *) return 1 ;; esac } From patchwork Sun May 5 16:57:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yuan1" X-Patchwork-Id: 1931830 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=dZpAYYsQ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VXw4n6M7fz1xnS for ; Mon, 6 May 2024 18:46:49 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3tz9-0003Qj-OL; Mon, 06 May 2024 04:46:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyv-0003Ee-VI for qemu-devel@nongnu.org; Mon, 06 May 2024 04:45:58 -0400 Received: from mgamail.intel.com ([192.198.163.16]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyu-0003R3-34 for qemu-devel@nongnu.org; Mon, 06 May 2024 04:45:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714985156; x=1746521156; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=z2l/kZxF6ucmve0nR6QM982kPczxoQOncFJ70CSOlCI=; b=dZpAYYsQxfmM6ijVJU1K18lK7Qc+QpvXcg3ufz3zmgxyEWYg6R5sbh62 0l7ZwOVGbVBKx5ee8iMvTvuYOTHQax4Tg7QWWrm5AXXAGvs99I0Oo4ztC 7qxylQAUby477ZpCM6Y87XgeaDIvBEtx8bpS2tVOoBI7JwbNRxZJJSym9 v+qC3RRH5UaKjezLUnWHBUz5mmNSzQvAauiYmeSrteoHzfctJ3a0ZC0pP /8JIAK0QupkhuwwjkQSMslwkAXjH4Anmbxg+ewufdMdy6Ns7lhAqT5NPz vdY7XGuXJDnpYCFp3wKXXUMTtWA8lrLi6w8B73swguYyh60Ash1fjFR0H Q==; X-CSE-ConnectionGUID: 7K+G+mxoSVaPwbxmvsbY+g== X-CSE-MsgGUID: oftrFUSOSei7LGHGyVrEyg== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="11254997" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="11254997" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 May 2024 01:45:55 -0700 X-CSE-ConnectionGUID: Xr3dABfyTWmdf4Reg9LjpQ== X-CSE-MsgGUID: kRAOcOy3SBWFAVETf+bmxw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="51287533" Received: from sae-gw02.sh.intel.com (HELO localhost) ([10.239.45.110]) by fmviesa002.fm.intel.com with ESMTP; 06 May 2024 01:45:54 -0700 From: Yuan Liu To: peterx@redhat.com, farosas@suse.de Cc: qemu-devel@nongnu.org, yuan1.liu@intel.com, nanhai.zou@intel.com Subject: [PATCH v6 4/7] migration/multifd: add qpl compression method Date: Mon, 6 May 2024 00:57:48 +0800 Message-Id: <20240505165751.2392198-5-yuan1.liu@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240505165751.2392198-1-yuan1.liu@intel.com> References: <20240505165751.2392198-1-yuan1.liu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.16; envelope-from=yuan1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -37 X-Spam_score: -3.8 X-Spam_bar: --- X-Spam_report: (-3.8 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.431, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org add the Query Processing Library (QPL) compression method Introduce the qpl as a new multifd migration compression method, it can use In-Memory Analytics Accelerator(IAA) to accelerate compression and decompression, which can not only reduce network bandwidth requirement but also reduce host compression and decompression CPU overhead. How to enable qpl compression during migration: migrate_set_parameter multifd-compression qpl The qpl method only supports one compression level, there is no qpl compression level parameter added, users do not need to specify the qpl compression level. Signed-off-by: Yuan Liu Reviewed-by: Nanhai Zou --- hw/core/qdev-properties-system.c | 2 +- migration/meson.build | 1 + migration/multifd-qpl.c | 20 ++++++++++++++++++++ migration/multifd.h | 1 + qapi/migration.json | 7 ++++++- 5 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 migration/multifd-qpl.c diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index d79d6f4b53..6ccd7224f6 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -659,7 +659,7 @@ const PropertyInfo qdev_prop_fdc_drive_type = { const PropertyInfo qdev_prop_multifd_compression = { .name = "MultiFDCompression", .description = "multifd_compression values, " - "none/zlib/zstd", + "none/zlib/zstd/qpl", .enum_table = &MultiFDCompression_lookup, .get = qdev_propinfo_get_enum, .set = qdev_propinfo_set_enum, diff --git a/migration/meson.build b/migration/meson.build index f76b1ba328..1d432d5328 100644 --- a/migration/meson.build +++ b/migration/meson.build @@ -43,6 +43,7 @@ if get_option('live_block_migration').allowed() system_ss.add(files('block.c')) endif system_ss.add(when: zstd, if_true: files('multifd-zstd.c')) +system_ss.add(when: qpl, if_true: files('multifd-qpl.c')) specific_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_true: files('ram.c', diff --git a/migration/multifd-qpl.c b/migration/multifd-qpl.c new file mode 100644 index 0000000000..056a68a060 --- /dev/null +++ b/migration/multifd-qpl.c @@ -0,0 +1,20 @@ +/* + * Multifd qpl compression accelerator implementation + * + * Copyright (c) 2023 Intel Corporation + * + * Authors: + * Yuan Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "qemu/osdep.h" +#include "qemu/module.h" + +static void multifd_qpl_register(void) +{ + /* noop */ +} + +migration_init(multifd_qpl_register); diff --git a/migration/multifd.h b/migration/multifd.h index c9d9b09239..5b7d9b15f8 100644 --- a/migration/multifd.h +++ b/migration/multifd.h @@ -40,6 +40,7 @@ MultiFDRecvData *multifd_get_recv_data(void); #define MULTIFD_FLAG_NOCOMP (0 << 1) #define MULTIFD_FLAG_ZLIB (1 << 1) #define MULTIFD_FLAG_ZSTD (2 << 1) +#define MULTIFD_FLAG_QPL (4 << 1) /* This value needs to be a multiple of qemu_target_page_size() */ #define MULTIFD_PACKET_SIZE (512 * 1024) diff --git a/qapi/migration.json b/qapi/migration.json index 8c65b90328..854e8609bd 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -628,11 +628,16 @@ # # @zstd: use zstd compression method. # +# @qpl: use qpl compression method. Query Processing Library(qpl) is based on +# the deflate compression algorithm and use the Intel In-Memory Analytics +# Accelerator(IAA) accelerated compression and decompression. (Since 9.1) +# # Since: 5.0 ## { 'enum': 'MultiFDCompression', 'data': [ 'none', 'zlib', - { 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] } + { 'name': 'zstd', 'if': 'CONFIG_ZSTD' }, + { 'name': 'qpl', 'if': 'CONFIG_QPL' } ] } ## # @MigMode: From patchwork Sun May 5 16:57:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yuan1" X-Patchwork-Id: 1931828 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=mijJXX4q; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VXw4P5tywz1xnS for ; Mon, 6 May 2024 18:46:29 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3tzF-0003YD-Bs; Mon, 06 May 2024 04:46:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tz0-0003JG-QI for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:03 -0400 Received: from mgamail.intel.com ([198.175.65.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyy-0003VD-Jw for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714985161; x=1746521161; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TWvvo2ZUcZJTf/RJ2s+gk/AmBE13Gi7wGQTccvhdV9s=; b=mijJXX4qboYQkIOqbLaH/7MQ2m0iAW5KSDCCRR/TGafktbpyvCepujYZ H0lLc09xHbUn8EgN7K9ZaEk/FMxlYBBMThcHGupGsS1lH2OpuonE5+Jjg MTYm62RvV/KwxyWbcwEJGN+K3DX8taKphPeZLFh7SueRFsQtrM+IdOTYB nQTPvWxyDyK84SHdO7pMJMxIDOumy6nxkY1ldaQB96HwUsViOwdfY07/B zM8YIQQU3MWUH8AZiQDeeeDcZDQZPUTGi3n6JB7qNCIlUPfIbb1zTKW9c iLN0wW3wziQnTp7IwlwoJJZWCXFG7mQUmukT7+xrhQ06kohQ7SBHSUeT5 w==; X-CSE-ConnectionGUID: +0elOk/eRvG95j7j6Iff2Q== X-CSE-MsgGUID: elOAZnsGR02q7V+Vfa2jMA== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="21875808" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="21875808" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 May 2024 01:45:58 -0700 X-CSE-ConnectionGUID: 3ZD02ceGTEasMJFbpgK1gA== X-CSE-MsgGUID: tnMDIF5dS/qDeBNJuaJeYQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28203254" Received: from sae-gw02.sh.intel.com (HELO localhost) ([10.239.45.110]) by fmviesa006.fm.intel.com with ESMTP; 06 May 2024 01:45:56 -0700 From: Yuan Liu To: peterx@redhat.com, farosas@suse.de Cc: qemu-devel@nongnu.org, yuan1.liu@intel.com, nanhai.zou@intel.com Subject: [PATCH v6 5/7] migration/multifd: implement initialization of qpl compression Date: Mon, 6 May 2024 00:57:49 +0800 Message-Id: <20240505165751.2392198-6-yuan1.liu@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240505165751.2392198-1-yuan1.liu@intel.com> References: <20240505165751.2392198-1-yuan1.liu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=198.175.65.13; envelope-from=yuan1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -37 X-Spam_score: -3.8 X-Spam_bar: --- X-Spam_report: (-3.8 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.431, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org the qpl initialization includes memory allocation for compressed data and the qpl job initialization. the qpl job initialization will check if the In-Memory Analytics Accelerator(IAA) device is available and use the IAA device first. If the platform does not have IAA device or the IAA device is not available, the qpl compression will fallback to the software path. Signed-off-by: Yuan Liu Reviewed-by: Nanhai Zou --- migration/multifd-qpl.c | 272 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 271 insertions(+), 1 deletion(-) diff --git a/migration/multifd-qpl.c b/migration/multifd-qpl.c index 056a68a060..89fa51091a 100644 --- a/migration/multifd-qpl.c +++ b/migration/multifd-qpl.c @@ -9,12 +9,282 @@ * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ + #include "qemu/osdep.h" #include "qemu/module.h" +#include "qapi/error.h" +#include "migration.h" +#include "multifd.h" +#include "qpl/qpl.h" + +typedef struct { + qpl_job **job_array; + /* the number of allocated jobs */ + uint32_t total_job_num; + /* compressed data buffer */ + uint8_t *zbuf; + /* the length of compressed data */ + uint32_t *zbuf_hdr; + /* the status of IAA device */ + bool iaa_avail; +} QplData; + +/** + * check_iaa_avail: check if IAA device is available + * + * If the system does not have an IAA device, the IAA device is + * not enabled or the IAA work queue is not configured as a shared + * mode, the QPL hardware path initialization will fail. + * + * Returns true if IAA device is available, otherwise false. + */ +static bool check_iaa_avail(void) +{ + qpl_job *job = NULL; + uint32_t job_size = 0; + qpl_path_t path = qpl_path_hardware; + + if (qpl_get_job_size(path, &job_size) != QPL_STS_OK) { + return false; + } + job = g_malloc0(job_size); + if (qpl_init_job(path, job) != QPL_STS_OK) { + g_free(job); + return false; + } + g_free(job); + return true; +} + +/** + * multifd_qpl_free_jobs: cleanup jobs + * + * Free all job resources. + * + * @qpl: pointer to the QplData structure + */ +static void multifd_qpl_free_jobs(QplData *qpl) +{ + assert(qpl != NULL); + for (int i = 0; i < qpl->total_job_num; i++) { + qpl_fini_job(qpl->job_array[i]); + g_free(qpl->job_array[i]); + qpl->job_array[i] = NULL; + } + g_free(qpl->job_array); + qpl->job_array = NULL; +} + +/** + * multifd_qpl_init_jobs: initialize jobs + * + * Initialize all jobs + * + * @qpl: pointer to the QplData structure + * @chan_id: multifd channel number + * @errp: pointer to an error + */ +static int multifd_qpl_init_jobs(QplData *qpl, uint8_t chan_id, Error **errp) +{ + qpl_path_t path; + qpl_status status; + uint32_t job_size = 0; + qpl_job *job = NULL; + + path = qpl->iaa_avail ? qpl_path_hardware : qpl_path_software; + status = qpl_get_job_size(path, &job_size); + if (status != QPL_STS_OK) { + error_setg(errp, "multifd: %u: qpl_get_job_size failed with error %d", + chan_id, status); + return -1; + } + qpl->job_array = g_new0(qpl_job *, qpl->total_job_num); + for (int i = 0; i < qpl->total_job_num; i++) { + job = g_malloc0(job_size); + status = qpl_init_job(path, job); + if (status != QPL_STS_OK) { + error_setg(errp, "multifd: %u: qpl_init_job failed with error %d", + chan_id, status); + multifd_qpl_free_jobs(qpl); + return -1; + } + qpl->job_array[i] = job; + } + return 0; +} + +/** + * multifd_qpl_init: initialize QplData structure + * + * Allocate and initialize a QplData structure + * + * Returns QplData pointer for success or NULL for error + * + * @job_num: pointer to the QplData structure + * @job_size: the buffer size of the job + * @chan_id: multifd channel number + * @errp: pointer to an error + */ +static QplData *multifd_qpl_init(uint32_t job_num, uint32_t job_size, + uint8_t chan_id, Error **errp) +{ + QplData *qpl; + + qpl = g_new0(QplData, 1); + qpl->total_job_num = job_num; + qpl->iaa_avail = check_iaa_avail(); + if (multifd_qpl_init_jobs(qpl, chan_id, errp) != 0) { + g_free(qpl); + return NULL; + } + qpl->zbuf = g_malloc0(job_size * job_num); + qpl->zbuf_hdr = g_new0(uint32_t, job_num); + return qpl; +} + +/** + * multifd_qpl_deinit: cleanup QplData structure + * + * Free jobs, comprssed buffers and QplData structure + * + * @qpl: pointer to the QplData structure + */ +static void multifd_qpl_deinit(QplData *qpl) +{ + if (qpl != NULL) { + multifd_qpl_free_jobs(qpl); + g_free(qpl->zbuf_hdr); + g_free(qpl->zbuf); + g_free(qpl); + } +} + +/** + * multifd_qpl_send_setup: setup send side + * + * Setup each channel with QPL compression. + * + * Returns 0 for success or -1 for error + * + * @p: Params for the channel that we are using + * @errp: pointer to an error + */ +static int multifd_qpl_send_setup(MultiFDSendParams *p, Error **errp) +{ + QplData *qpl; + + qpl = multifd_qpl_init(p->page_count, p->page_size, p->id, errp); + if (!qpl) { + return -1; + } + p->compress_data = qpl; + + /* + * Each page will be compressed independently and sent using an IOV. The + * additional two IOVs are used to store packet header and compressed data + * length + */ + p->iov = g_new0(struct iovec, p->page_count + 2); + return 0; +} + +/** + * multifd_qpl_send_cleanup: cleanup send side + * + * Close the channel and return memory. + * + * @p: Params for the channel that we are using + * @errp: pointer to an error + */ +static void multifd_qpl_send_cleanup(MultiFDSendParams *p, Error **errp) +{ + multifd_qpl_deinit(p->compress_data); + p->compress_data = NULL; + g_free(p->iov); + p->iov = NULL; +} + +/** + * multifd_qpl_send_prepare: prepare data to be able to send + * + * Create a compressed buffer with all the pages that we are going to + * send. + * + * Returns 0 for success or -1 for error + * + * @p: Params for the channel that we are using + * @errp: pointer to an error + */ +static int multifd_qpl_send_prepare(MultiFDSendParams *p, Error **errp) +{ + /* Implement in next patch */ + return -1; +} + +/** + * multifd_qpl_recv_setup: setup receive side + * + * Create the compressed channel and buffer. + * + * Returns 0 for success or -1 for error + * + * @p: Params for the channel that we are using + * @errp: pointer to an error + */ +static int multifd_qpl_recv_setup(MultiFDRecvParams *p, Error **errp) +{ + QplData *qpl; + + qpl = multifd_qpl_init(p->page_count, p->page_size, p->id, errp); + if (!qpl) { + return -1; + } + p->compress_data = qpl; + return 0; +} + +/** + * multifd_qpl_recv_cleanup: setup receive side + * + * Close the channel and return memory. + * + * @p: Params for the channel that we are using + */ +static void multifd_qpl_recv_cleanup(MultiFDRecvParams *p) +{ + multifd_qpl_deinit(p->compress_data); + p->compress_data = NULL; +} + +/** + * multifd_qpl_recv: read the data from the channel into actual pages + * + * Read the compressed buffer, and uncompress it into the actual + * pages. + * + * Returns 0 for success or -1 for error + * + * @p: Params for the channel that we are using + * @errp: pointer to an error + */ +static int multifd_qpl_recv(MultiFDRecvParams *p, Error **errp) +{ + /* Implement in next patch */ + return -1; +} + +static MultiFDMethods multifd_qpl_ops = { + .send_setup = multifd_qpl_send_setup, + .send_cleanup = multifd_qpl_send_cleanup, + .send_prepare = multifd_qpl_send_prepare, + .recv_setup = multifd_qpl_recv_setup, + .recv_cleanup = multifd_qpl_recv_cleanup, + .recv = multifd_qpl_recv, +}; static void multifd_qpl_register(void) { - /* noop */ + multifd_register_ops(MULTIFD_COMPRESSION_QPL, &multifd_qpl_ops); } migration_init(multifd_qpl_register); From patchwork Sun May 5 16:57:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yuan1" X-Patchwork-Id: 1931834 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=J13Wlki6; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VXw5Q2mPsz1xnS for ; Mon, 6 May 2024 18:47:22 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3tzD-0003Wk-Ny; Mon, 06 May 2024 04:46:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tz1-0003JT-SB for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:04 -0400 Received: from mgamail.intel.com ([198.175.65.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tyz-0003RW-DZ for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714985162; x=1746521162; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qdUrXPsPBZ7F0XCMTfsKUaEO5h8p2wDUFrkMI1B7RfI=; b=J13Wlki6nukH5ty2MNo/557ofsJ6QImbMHW//GpfJ5OQZ9AO+JL1GJqn MNTvHbXzZbBQdRbfyjCxOGfRk/ne57zlzVdPa1RnA8rX/9pehcR6fOoUU IVuZ6m4HWf8KyX+I9qplOgkGMHIXMlWkpszVsSCqhEo5j2elY2YTEIC6Q 9co+7jrGxb0wYVyYtu0qwzPCerQBMtaGic5If9nUIKK6bbhhokpCdZpET WvGLm+P4rNliOyRWHiLq7Av+zSyJbP6ZDsCbb1TgZDJ0tn25nqzmkqlqa SgbLPQ3wM4Tq2MCEAi/YjAGslji2o5yrtSD1RmLN7eCS/wC65JxxMJOh+ w==; X-CSE-ConnectionGUID: zUzH4yOpSBqeR7VTMa5iHw== X-CSE-MsgGUID: 4e2eDCPMSbiFsxWE0U1UsA== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="21875812" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="21875812" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 May 2024 01:46:01 -0700 X-CSE-ConnectionGUID: CJ6ZI3yRQ16EQoKjq8hhjw== X-CSE-MsgGUID: 81pN6IuXR2GjahcR9QnjJQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28203257" Received: from sae-gw02.sh.intel.com (HELO localhost) ([10.239.45.110]) by fmviesa006.fm.intel.com with ESMTP; 06 May 2024 01:45:58 -0700 From: Yuan Liu To: peterx@redhat.com, farosas@suse.de Cc: qemu-devel@nongnu.org, yuan1.liu@intel.com, nanhai.zou@intel.com Subject: [PATCH v6 6/7] migration/multifd: implement qpl compression and decompression Date: Mon, 6 May 2024 00:57:50 +0800 Message-Id: <20240505165751.2392198-7-yuan1.liu@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240505165751.2392198-1-yuan1.liu@intel.com> References: <20240505165751.2392198-1-yuan1.liu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=198.175.65.13; envelope-from=yuan1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -37 X-Spam_score: -3.8 X-Spam_bar: --- X-Spam_report: (-3.8 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.431, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org each qpl job is used to (de)compress a normal page and it can be processed independently by the IAA hardware. All qpl jobs are submitted to the hardware at once, and wait for all jobs completion. If hardware path(IAA) is not available, use software for compression and decompression. Signed-off-by: Yuan Liu Reviewed-by: Nanhai Zou --- migration/multifd-qpl.c | 284 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 280 insertions(+), 4 deletions(-) diff --git a/migration/multifd-qpl.c b/migration/multifd-qpl.c index 89fa51091a..9a1fddbdd0 100644 --- a/migration/multifd-qpl.c +++ b/migration/multifd-qpl.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "qemu/module.h" #include "qapi/error.h" +#include "exec/ramblock.h" #include "migration.h" #include "multifd.h" #include "qpl/qpl.h" @@ -204,6 +205,139 @@ static void multifd_qpl_send_cleanup(MultiFDSendParams *p, Error **errp) p->iov = NULL; } +/** + * multifd_qpl_prepare_job: prepare a compression or decompression job + * + * Prepare a compression or decompression job and configure job attributes + * including job compression level and flags. + * + * @job: pointer to the QplData structure + * @is_compression: compression or decompression indication + * @input: pointer to the input data buffer + * @input_len: the length of the input data + * @output: pointer to the output data buffer + * @output_len: the size of the output data buffer + */ +static void multifd_qpl_prepare_job(qpl_job *job, bool is_compression, + uint8_t *input, uint32_t input_len, + uint8_t *output, uint32_t output_len) +{ + job->op = is_compression ? qpl_op_compress : qpl_op_decompress; + job->next_in_ptr = input; + job->next_out_ptr = output; + job->available_in = input_len; + job->available_out = output_len; + job->flags = QPL_FLAG_FIRST | QPL_FLAG_LAST | QPL_FLAG_OMIT_VERIFY; + /* only supports one compression level */ + job->level = 1; +} + +/** + * multifd_qpl_build_packet: build a qpl compressed data packet + * + * The qpl compressed data packet consists of two parts, one part stores + * the compressed length of each page, and the other part is the compressed + * data of each page. The zbuf_hdr stores the compressed length of all pages, + * and use a separate IOV to store the compressed data of each page. + * + * @qpl: pointer to the QplData structure + * @p: Params for the channel that we are using + * @idx: The index of the compressed length array + * @addr: pointer to the compressed data + * @len: The length of the compressed data + */ +static void multifd_qpl_build_packet(QplData *qpl, MultiFDSendParams *p, + uint32_t idx, uint8_t *addr, uint32_t len) +{ + qpl->zbuf_hdr[idx] = cpu_to_be32(len); + p->iov[p->iovs_num].iov_base = addr; + p->iov[p->iovs_num].iov_len = len; + p->iovs_num++; + p->next_packet_size += len; +} + +/** + * multifd_qpl_compress_pages: compress normal pages + * + * Each normal page will be compressed independently, and the compression jobs + * will be submitted to the IAA hardware in non-blocking mode, waiting for all + * jobs to be completed and filling the compressed length and data into the + * sending IOVs. If IAA device is not available, the software path is used. + * + * Returns 0 for success or -1 for error + * + * @p: Params for the channel that we are using + * @errp: pointer to an error + */ +static int multifd_qpl_compress_pages(MultiFDSendParams *p, Error **errp) +{ + qpl_status status; + QplData *qpl = p->compress_data; + MultiFDPages_t *pages = p->pages; + uint8_t *zbuf = qpl->zbuf; + uint8_t *host = pages->block->host; + uint32_t job_num = pages->normal_num; + qpl_job *job = NULL; + + assert(job_num <= qpl->total_job_num); + /* submit all compression jobs */ + for (int i = 0; i < job_num; i++) { + job = qpl->job_array[i]; + multifd_qpl_prepare_job(job, true, host + pages->offset[i], + p->page_size, zbuf, p->page_size - 1); + /* if hardware path(IAA) is unavailable, call the software path */ + if (!qpl->iaa_avail) { + status = qpl_execute_job(job); + if (status == QPL_STS_OK) { + multifd_qpl_build_packet(qpl, p, i, zbuf, job->total_out); + } else if (status == QPL_STS_MORE_OUTPUT_NEEDED) { + /* compressed length exceeds page size, send page directly */ + multifd_qpl_build_packet(qpl, p, i, host + pages->offset[i], + p->page_size); + } else { + error_setg(errp, "multifd %u: qpl_execute_job error %d", + p->id, status); + return -1; + } + zbuf += p->page_size; + continue; + } +retry: + status = qpl_submit_job(job); + if (status == QPL_STS_OK) { + zbuf += p->page_size; + } else if (status == QPL_STS_QUEUES_ARE_BUSY_ERR) { + goto retry; + } else { + error_setg(errp, "multifd %u: qpl_submit_job failed with error %d", + p->id, status); + return -1; + } + } + if (!qpl->iaa_avail) { + goto done; + } + /* wait all jobs to complete for hardware(IAA) path */ + for (int i = 0; i < job_num; i++) { + job = qpl->job_array[i]; + status = qpl_wait_job(job); + if (status == QPL_STS_OK) { + multifd_qpl_build_packet(qpl, p, i, qpl->zbuf + (p->page_size * i), + job->total_out); + } else if (status == QPL_STS_MORE_OUTPUT_NEEDED) { + /* compressed data length exceeds page size, send page directly */ + multifd_qpl_build_packet(qpl, p, i, host + pages->offset[i], + p->page_size); + } else { + error_setg(errp, "multifd %u: qpl_wait_job failed with error %d", + p->id, status); + return -1; + } + } +done: + return 0; +} + /** * multifd_qpl_send_prepare: prepare data to be able to send * @@ -217,8 +351,28 @@ static void multifd_qpl_send_cleanup(MultiFDSendParams *p, Error **errp) */ static int multifd_qpl_send_prepare(MultiFDSendParams *p, Error **errp) { - /* Implement in next patch */ - return -1; + QplData *qpl = p->compress_data; + uint32_t hdr_size; + + if (!multifd_send_prepare_common(p)) { + goto out; + } + + assert(p->pages->normal_num <= qpl->total_job_num); + hdr_size = p->pages->normal_num * sizeof(uint32_t); + /* prepare the header that stores the lengths of all compressed data */ + p->iov[1].iov_base = (uint8_t *) qpl->zbuf_hdr; + p->iov[1].iov_len = hdr_size; + p->iovs_num++; + p->next_packet_size += hdr_size; + if (multifd_qpl_compress_pages(p, errp) != 0) { + return -1; + } + +out: + p->flags |= MULTIFD_FLAG_QPL; + multifd_send_fill_packet(p); + return 0; } /** @@ -256,6 +410,88 @@ static void multifd_qpl_recv_cleanup(MultiFDRecvParams *p) p->compress_data = NULL; } +/** + * multifd_qpl_decompress_pages: decompress normal pages + * + * Each compressed page will be decompressed independently, and the + * decompression jobs will be submitted to the IAA hardware in non-blocking + * mode, waiting for all jobs to be completed and loading the decompressed + * data into guest memory. If IAA device is not available, the software path + * is used. + * + * Returns 0 for success or -1 for error + * + * @p: Params for the channel that we are using + * @errp: pointer to an error + */ +static int multifd_qpl_decompress_pages(MultiFDRecvParams *p, Error **errp) +{ + qpl_status status; + qpl_job *job; + QplData *qpl = p->compress_data; + uint32_t job_num = p->normal_num; + uint32_t off = 0; + + assert(job_num <= qpl->total_job_num); + /* submit all decompression jobs */ + for (int i = 0; i < job_num; i++) { + /* if the data size is the same as the page size, load it directly */ + if (qpl->zbuf_hdr[i] == p->page_size) { + memcpy(p->host + p->normal[i], qpl->zbuf + off, p->page_size); + off += p->page_size; + continue; + } + job = qpl->job_array[i]; + multifd_qpl_prepare_job(job, false, qpl->zbuf + off, qpl->zbuf_hdr[i], + p->host + p->normal[i], p->page_size); + /* if hardware path(IAA) is unavailable, call the software path */ + if (!qpl->iaa_avail) { + status = qpl_execute_job(job); + if (status == QPL_STS_OK) { + off += qpl->zbuf_hdr[i]; + continue; + } + error_setg(errp, "multifd %u: qpl_execute_job failed with error %d", + p->id, status); + return -1; + } +retry: + status = qpl_submit_job(job); + if (status == QPL_STS_OK) { + off += qpl->zbuf_hdr[i]; + } else if (status == QPL_STS_QUEUES_ARE_BUSY_ERR) { + goto retry; + } else { + error_setg(errp, "multifd %u: qpl_submit_job failed with error %d", + p->id, status); + return -1; + } + } + if (!qpl->iaa_avail) { + goto done; + } + /* wait all jobs to complete for hardware(IAA) path */ + for (int i = 0; i < job_num; i++) { + if (qpl->zbuf_hdr[i] == p->page_size) { + continue; + } + job = qpl->job_array[i]; + status = qpl_wait_job(job); + if (status != QPL_STS_OK) { + error_setg(errp, "multifd %u: qpl_wait_job failed with error %d", + p->id, status); + return -1; + } + if (job->total_out != p->page_size) { + error_setg(errp, "multifd %u: decompressed len %u, expected len %u", + p->id, job->total_out, p->page_size); + return -1; + } + } +done: + return 0; +} + /** * multifd_qpl_recv: read the data from the channel into actual pages * @@ -269,8 +505,48 @@ static void multifd_qpl_recv_cleanup(MultiFDRecvParams *p) */ static int multifd_qpl_recv(MultiFDRecvParams *p, Error **errp) { - /* Implement in next patch */ - return -1; + QplData *qpl = p->compress_data; + uint32_t in_size = p->next_packet_size; + uint32_t flags = p->flags & MULTIFD_FLAG_COMPRESSION_MASK; + uint32_t hdr_len = p->normal_num * sizeof(uint32_t); + uint32_t data_len = 0; + int ret; + + if (flags != MULTIFD_FLAG_QPL) { + error_setg(errp, "multifd %u: flags received %x flags expected %x", + p->id, flags, MULTIFD_FLAG_QPL); + return -1; + } + multifd_recv_zero_page_process(p); + if (!p->normal_num) { + assert(in_size == 0); + return 0; + } + + /* read compressed data lengths */ + assert(hdr_len < in_size); + ret = qio_channel_read_all(p->c, (void *) qpl->zbuf_hdr, hdr_len, errp); + if (ret != 0) { + return ret; + } + assert(p->normal_num <= qpl->total_job_num); + for (int i = 0; i < p->normal_num; i++) { + qpl->zbuf_hdr[i] = be32_to_cpu(qpl->zbuf_hdr[i]); + data_len += qpl->zbuf_hdr[i]; + assert(qpl->zbuf_hdr[i] <= p->page_size); + } + + /* read compressed data */ + assert(in_size == hdr_len + data_len); + ret = qio_channel_read_all(p->c, (void *) qpl->zbuf, data_len, errp); + if (ret != 0) { + return ret; + } + + if (multifd_qpl_decompress_pages(p, errp) != 0) { + return -1; + } + return 0; } static MultiFDMethods multifd_qpl_ops = { From patchwork Sun May 5 16:57:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yuan1" X-Patchwork-Id: 1931832 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=XfBGIWRl; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VXw5F3SQMz1xnS for ; Mon, 6 May 2024 18:47:13 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3tzJ-0003hX-NP; Mon, 06 May 2024 04:46:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tz3-0003LT-Pw for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:05 -0400 Received: from mgamail.intel.com ([192.198.163.16]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s3tz2-0003XA-3R for qemu-devel@nongnu.org; Mon, 06 May 2024 04:46:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714985164; x=1746521164; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=i4b2WuDGoF1FnltOM1bdaEoGjw6nQCDEPh+AYW8me4Y=; b=XfBGIWRl25q9JinLm/u8G51886yTKcyvo48znVL2brsoCPT4cq8MzyHY NOp3zYEPcm+EylA28rR+qphG8vdwhUvZFPeys2g2A2BZRejw4qdtQIvIb RWS37PQ8cB5EIQ1RhcdKuw4skFfuHiMtN75y44o+mfg5d87KoJHnUPOmn YaS9p2kjYnK39JUDFx1QUEcJ7XVW6ogEMZ5j/SFfLlr2yNH1uB2vY+JPS LIRSsQjSWX2KnmYUTW+2DXLpK5nOthz3iPYz4R6tsWfGlLurr1Yd11OfL VvHM+yPz4NlG33OatDDQq+oQt5E5rv55UiphWbwPj+5DcGD6j2ZEUOUmx w==; X-CSE-ConnectionGUID: 9tI5h7IjQkaxuVPIOswv7Q== X-CSE-MsgGUID: O5pu1GeOT2GBG9nD1QurYA== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="11255010" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="11255010" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 May 2024 01:46:02 -0700 X-CSE-ConnectionGUID: hTM2e8ziS8qv9zQmgRblXg== X-CSE-MsgGUID: 8IbRaBZKQAWI1q+9ocdTog== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="51287583" Received: from sae-gw02.sh.intel.com (HELO localhost) ([10.239.45.110]) by fmviesa002.fm.intel.com with ESMTP; 06 May 2024 01:46:01 -0700 From: Yuan Liu To: peterx@redhat.com, farosas@suse.de Cc: qemu-devel@nongnu.org, yuan1.liu@intel.com, nanhai.zou@intel.com Subject: [PATCH v6 7/7] tests/migration-test: add qpl compression test Date: Mon, 6 May 2024 00:57:51 +0800 Message-Id: <20240505165751.2392198-8-yuan1.liu@intel.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240505165751.2392198-1-yuan1.liu@intel.com> References: <20240505165751.2392198-1-yuan1.liu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.16; envelope-from=yuan1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -37 X-Spam_score: -3.8 X-Spam_bar: --- X-Spam_report: (-3.8 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.431, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org add qpl to compression method test for multifd migration the qpl compression supports software path and hardware path(IAA device), and the hardware path is used first by default. If the hardware path is unavailable, it will automatically fallback to the software path for testing. Signed-off-by: Yuan Liu Reviewed-by: Nanhai Zou Reviewed-by: Peter Xu --- tests/qtest/migration-test.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 5d6d8cd634..0f75ed7c49 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -2777,6 +2777,15 @@ test_migrate_precopy_tcp_multifd_zstd_start(QTestState *from, } #endif /* CONFIG_ZSTD */ +#ifdef CONFIG_QPL +static void * +test_migrate_precopy_tcp_multifd_qpl_start(QTestState *from, + QTestState *to) +{ + return test_migrate_precopy_tcp_multifd_start_common(from, to, "qpl"); +} +#endif /* CONFIG_QPL */ + static void test_multifd_tcp_uri_none(void) { MigrateCommon args = { @@ -2857,6 +2866,17 @@ static void test_multifd_tcp_zstd(void) } #endif +#ifdef CONFIG_QPL +static void test_multifd_tcp_qpl(void) +{ + MigrateCommon args = { + .listen_uri = "defer", + .start_hook = test_migrate_precopy_tcp_multifd_qpl_start, + }; + test_precopy_common(&args); +} +#endif + #ifdef CONFIG_GNUTLS static void * test_migrate_multifd_tcp_tls_psk_start_match(QTestState *from, @@ -3760,6 +3780,10 @@ int main(int argc, char **argv) migration_test_add("/migration/multifd/tcp/plain/zstd", test_multifd_tcp_zstd); #endif +#ifdef CONFIG_QPL + migration_test_add("/migration/multifd/tcp/plain/qpl", + test_multifd_tcp_qpl); +#endif #ifdef CONFIG_GNUTLS migration_test_add("/migration/multifd/tcp/tls/psk/match", test_multifd_tcp_tls_psk_match);