@@ -1271,6 +1271,9 @@ F: doc/guides/compressdevs/features/zlib.ini
ZTE Storage Data Accelerator(ZSDA)
M: Hanxiao Li <li.hanxiao@zte.com.cn>
F: drivers/common/zsda/
+F: drivers/compress/zsda/
+F: doc/guides/compressdevs/zsda.rst
+F: doc/guides/compressdevs/features/zsda.ini
DMAdev Drivers
--------------
new file mode 100644
@@ -0,0 +1,6 @@
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+; Supported features of 'ZSDA' compression driver.
+;
+[Features]
@@ -17,3 +17,4 @@ Compression Device Drivers
qat_comp
uadk
zlib
+ zsda
new file mode 100644
@@ -0,0 +1,178 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2024 ZTE Corporation.
+
+ZTE Storage Data Accelerator (ZSDA) Poll Mode Driver
+=======================================================
+
+The ZSDA compression PMD provides poll mode compression & decompression driver
+support for the following hardware accelerator devices:
+
+* ``ZTE Processing accelerators 1cf2``
+
+
+Features
+--------
+
+
+Installation
+------------
+
+The ZSDA compression PMD is built by default with a standard DPDK build.
+
+It depends on a ZSDA kernel driver, see :ref:`building_zsda`.
+
+
+.. _building_zsda:
+
+Building PMDs on ZSDA
+---------------------
+
+A ZSDA device can host multiple acceleration services:
+
+* data compression
+
+These services are provided to DPDK applications via PMDs which register to
+implement the compressdev APIs. The PMDs use common ZSDA driver code
+which manages the ZSDA PCI device.
+
+
+Configuring and Building the DPDK ZSDA PMDs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Further information on configuring, building and installing DPDK is described
+:doc:`here <../linux_gsg/build_dpdk>`.
+
+.. _building_zsda_config:
+
+Build Configuration
+~~~~~~~~~~~~~~~~~~~
+These is the build configuration options affecting ZSDA, and its default values:
+
+.. code-block:: console
+
+ RTE_PMD_ZSDA_MAX_PCI_DEVICES=256
+
+
+Device and driver naming
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+* The zsda compressdev driver name is "compress_zsda".
+ The rte_compressdev_devices_get() returns the devices exposed by this driver.
+
+* Each zsda compression device has a unique name, in format
+ <pci bdf>, e.g. "0000:cc:00.3_zsda".
+ This name can be passed to rte_compressdev_get_dev_id() to get the device_id.
+
+
+Enable VFs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instructions for installation are below, but first an explanation of the
+relationships between the PF/VF devices and the PMDs visible to
+DPDK applications.
+
+Each ZSDA PF device exposes a number of VF devices. Each VF device can
+enable one compressdev PMD.
+
+These ZSDA PMDs share the same underlying device and pci-mgmt code, but are
+enumerated independently on their respective APIs and appear as independent
+devices to applications.
+
+.. Note::
+
+ Each VF can only be used by one DPDK process. It is not possible to share
+ the same VF across multiple processes, even if these processes are using
+ different acceleration services.
+ Conversely one DPDK process can use one or more ZSDA VFs and can expose
+ compressdev instances on each of those VFs.
+
+
+The examples below are based on the 1cf2 device, if you have a different device
+use the corresponding values in the above table.
+
+In BIOS ensure that SRIOV is enabled and either:
+
+* Disable VT-d or
+* Enable VT-d and set ``"intel_iommu=on iommu=pt"`` in the grub file.
+
+you need to expose the Virtual Functions (VFs) using the sysfs file system.
+
+First find the BDFs (Bus-Device-Function) of the physical functions (PFs) of
+your device, e.g.::
+
+ lspci -d:8050
+
+You should see output similar to::
+
+
+ cc:00.4 Processing accelerators: Device 1cf2:8050 (rev 01)
+ ce:00.3 Processing accelerators: Device 1cf2:8050 (rev 01)
+ d0:00.3 Processing accelerators: Device 1cf2:8050 (rev 01)
+ d2:00.3 Processing accelerators: Device 1cf2:8050 (rev 01)
+
+Enable the VFs for each PF by echoing the number of VFs per PF to the pci driver::
+
+ echo 31 > /sys/bus/pci/device/0000:cc:00.4/sriov_numvfs
+ echo 31 > /sys/bus/pci/device/0000:ce:00.3/sriov_numvfs
+ echo 31 > /sys/bus/pci/device/0000:d0:00.3/sriov_numvfs
+ echo 31 > /sys/bus/pci/device/0000:d2:00.3/sriov_numvfs
+
+Check that the VFs are available for use. For example ``lspci -d:8051`` should
+list 124 VF devices available.
+
+To complete the installation follow the instructions in
+`Binding the available VFs to the vfio-pci driver`_.
+
+.. Note::
+
+ If you see the following warning in ``/var/log/messages`` it can be ignored:
+ ``IOMMU should be enabled for SR-IOV to work correctly``.
+
+
+Binding the available VFs to the vfio-pci driver
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note:
+
+* Please note that due to security issues, the usage of older DPDK igb_uio
+ driver is not recommended. This document shows how to use the more secure
+ vfio-pci driver.
+
+Unbind the VFs from the stock driver so they can be bound to the vfio-pci driver.
+
+
+Bind to the vfio-pci driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Load the vfio-pci driver, bind the VF PCI Device id to it using the
+``dpdk-devbind.py`` script then use the ``--status`` option
+to confirm the VF devices are now in use by vfio-pci kernel driver,
+e.g. for the 1cf2 device::
+
+ cd to the top-level DPDK directory
+ modprobe vfio-pci
+ usertools/dpdk-devbind.py -b vfio-pci 0000:cc:01.4
+ usertools/dpdk-devbind.py --status
+
+Use ``modprobe vfio-pci disable_denylist=1`` from kernel 5.9 onwards.
+See note in the section `Binding the available VFs to the vfio-pci driver`_
+above.
+
+
+Testing
+~~~~~~~
+
+ZSDA compression PMD can be tested by running the test application::
+
+ cd ./<build_dir>/app/test
+ ./dpdk-test -l1 -n1 -a <your zsda bdf>
+ RTE>>compressdev_autotest
+
+
+Debugging
+~~~~~~~~~
+
+ZSDA logging feature can be enabled using the log-level option (where 8=maximum
+log level) on the process cmdline, e.g. using any of the following::
+
+ --log-level="gen,8"
@@ -7,9 +7,19 @@ if is_windows
subdir_done()
endif
-deps += ['bus_pci', 'mbuf']
+deps += ['bus_pci', 'mbuf', 'compressdev']
sources += files(
'zsda_device.c',
'zsda_logs.c',
'zsda_qp.c',
)
+
+zsda_compress = true
+zsda_compress_path = 'compress/zsda'
+zsda_compress_relpath = '../../' + zsda_compress_path
+includes += include_directories(zsda_compress_relpath)
+if zsda_compress
+ foreach f: ['zsda_comp_pmd.c']
+ sources += files(join_paths(zsda_compress_relpath, f))
+ endforeach
+endif
@@ -7,10 +7,10 @@
#include <rte_memzone.h>
#include "bus_pci_driver.h"
+#include "zsda_qp_common.h"
#define MAX_QPS_ON_FUNCTION 128
#define ZSDA_DEV_NAME_MAX_LEN 64
-#define ZSDA_MAX_SERVICES (0)
#define ZSDA_MAX_DEV RTE_PMD_ZSDA_MAX_PCI_DEVICES
struct zsda_device_info {
@@ -18,7 +18,11 @@ struct zsda_device_info {
/**< mz to store the: struct zsda_pci_device , so it can be
* shared across processes
*/
-
+ struct rte_device comp_rte_dev;
+ /**< This represents the compression subset of this pci device.
+ * Register with this rather than with the one in
+ * pci_dev so that its driver can have a compression-specific name
+ */
struct rte_pci_device *pci_dev;
};
@@ -46,6 +50,10 @@ struct zsda_pci_device {
struct rte_pci_device *pci_dev;
+ /* Data relating to compression service */
+ struct zsda_comp_dev_private *comp_dev;
+ /**< link back to compressdev private data */
+
struct zsda_qp_hw zsda_hw_qps[ZSDA_MAX_SERVICES];
uint16_t zsda_qp_hw_num[ZSDA_MAX_SERVICES];
};
@@ -3,15 +3,12 @@
*/
#include <stdint.h>
-
-#include <rte_malloc.h>
+#include <rte_mempool.h>
#include "zsda_logs.h"
-#include "zsda_device.h"
#include "zsda_qp.h"
#include "zsda_qp_common.h"
-
#define MAGIC_SEND 0xab
#define MAGIC_RECV 0xcd
#define ADMIN_VER 1
@@ -400,7 +397,8 @@ zsda_get_queue_cfg_by_id(const struct zsda_pci_device *zsda_pci_dev,
}
static struct ring_size zsda_qp_hw_ring_size[ZSDA_MAX_SERVICES] = {
-
+ [ZSDA_SERVICE_ENCOMPRESSION] = {32, 16},
+ [ZSDA_SERVICE_DECOMPRESSION] = {32, 16},
};
static int
@@ -468,6 +466,26 @@ zsda_unmask_flr(const struct zsda_pci_device *zsda_pci_dev)
return ZSDA_SUCCESS;
}
+static uint16_t
+zsda_qps_per_service(const struct zsda_pci_device *zsda_pci_dev,
+ const enum zsda_service_type service)
+{
+ uint16_t qp_hw_num = 0;
+
+ if (service < ZSDA_SERVICE_INVALID)
+ qp_hw_num = zsda_pci_dev->zsda_qp_hw_num[service];
+ return qp_hw_num;
+}
+
+struct zsda_num_qps zsda_nb_qps;
+static void
+zsda_get_nb_qps(const struct zsda_pci_device *zsda_pci_dev)
+{
+ zsda_nb_qps.encomp =
+ zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_ENCOMPRESSION);
+ zsda_nb_qps.decomp =
+ zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_DECOMPRESSION);
+}
int
zsda_queue_init(struct zsda_pci_device *zsda_pci_dev)
@@ -501,5 +519,7 @@ zsda_queue_init(struct zsda_pci_device *zsda_pci_dev)
return ret;
}
+ zsda_get_nb_qps(zsda_pci_dev);
+
return ret;
}
@@ -5,6 +5,8 @@
#ifndef _ZSDA_QP_H_
#define _ZSDA_QP_H_
+#include "zsda_device.h"
+
#define ZSDA_ADMIN_Q_START 0x100
#define ZSDA_ADMIN_Q_STOP 0x100
#define ZSDA_ADMIN_Q_STOP_RESP 0x104
@@ -72,10 +74,6 @@ enum zsda_admin_msg_id {
ZSDA_ADMIN_INT_TEST
};
-enum zsda_service_type {
- ZSDA_SERVICE_INVALID,
-};
-
struct ring_size {
uint16_t tx_msg_size;
uint16_t rx_msg_size;
@@ -118,7 +116,15 @@ struct zsda_admin_resp_qcfg {
uint8_t data[14];
} __rte_packed;
+struct zsda_num_qps {
+ uint16_t encomp;
+ uint16_t decomp;
+ uint16_t encrypt;
+ uint16_t decrypt;
+ uint16_t hash;
+};
+extern struct zsda_num_qps zsda_nb_qps;
int zsda_queue_start(const struct rte_pci_device *pci_dev);
int zsda_queue_stop(const struct rte_pci_device *pci_dev);
@@ -17,6 +17,13 @@
#define ZSDA_SUCCESS 0
#define ZSDA_FAILED (-1)
+enum zsda_service_type {
+ ZSDA_SERVICE_ENCOMPRESSION = 0,
+ ZSDA_SERVICE_DECOMPRESSION = 1,
+ ZSDA_SERVICE_INVALID,
+};
+#define ZSDA_MAX_SERVICES (2)
+
#define ZSDA_CSR_READ32(addr) rte_read32((addr))
#define ZSDA_CSR_WRITE32(addr, value) rte_write32((value), (addr))
#define ZSDA_CSR_READ16(addr) rte_read16((addr))
new file mode 100644
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#include <rte_malloc.h>
+
+#include "zsda_logs.h"
+#include "zsda_qp_common.h"
+#include "zsda_comp_pmd.h"
+
+static struct rte_compressdev_ops compress_zsda_ops = {
+
+ .dev_configure = NULL,
+ .dev_start = NULL,
+ .dev_stop = NULL,
+ .dev_close = NULL,
+ .dev_infos_get = NULL,
+
+ .stats_get = NULL,
+ .stats_reset = NULL,
+ .queue_pair_setup = NULL,
+ .queue_pair_release = NULL,
+
+ .private_xform_create = NULL,
+ .private_xform_free = NULL
+};
+
+/* An rte_driver is needed in the registration of the device with compressdev.
+ * The actual zsda pci's rte_driver can't be used as its name represents
+ * the whole pci device with all services. Think of this as a holder for a name
+ * for the compression part of the pci device.
+ */
+static const char zsda_comp_drv_name[] = RTE_STR(COMPRESSDEV_NAME_ZSDA_PMD);
+static const struct rte_driver compdev_zsda_driver = {
+ .name = zsda_comp_drv_name, .alias = zsda_comp_drv_name};
+
+int
+zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev)
+{
+ struct zsda_device_info *dev_info =
+ &zsda_devs[zsda_pci_dev->zsda_dev_id];
+
+ struct rte_compressdev_pmd_init_params init_params = {
+ .name = "",
+ .socket_id = (int)rte_socket_id(),
+ };
+
+ char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+ char capa_memz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+ struct rte_compressdev *compressdev;
+ struct zsda_comp_dev_private *comp_dev;
+ const struct rte_compressdev_capabilities *capabilities;
+ uint16_t capa_size = sizeof(struct rte_compressdev_capabilities);
+
+ snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",
+ zsda_pci_dev->name, "comp");
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ dev_info->comp_rte_dev.driver = &compdev_zsda_driver;
+ dev_info->comp_rte_dev.numa_node = dev_info->pci_dev->device.numa_node;
+ dev_info->comp_rte_dev.devargs = NULL;
+
+ compressdev = rte_compressdev_pmd_create(
+ name, &(dev_info->comp_rte_dev),
+ sizeof(struct zsda_comp_dev_private), &init_params);
+
+ if (compressdev == NULL)
+ return -ENODEV;
+
+ compressdev->dev_ops = &compress_zsda_ops;
+
+ compressdev->enqueue_burst = NULL;
+ compressdev->dequeue_burst = NULL;
+
+ compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
+
+ snprintf(capa_memz_name, RTE_COMPRESSDEV_NAME_MAX_LEN,
+ "ZSDA_COMP_CAPA");
+
+ comp_dev = compressdev->data->dev_private;
+ comp_dev->zsda_pci_dev = zsda_pci_dev;
+ comp_dev->compressdev = compressdev;
+
+ capabilities = NULL;
+
+ comp_dev->capa_mz = rte_memzone_lookup(capa_memz_name);
+ if (comp_dev->capa_mz == NULL) {
+ comp_dev->capa_mz = rte_memzone_reserve(
+ capa_memz_name, capa_size, rte_socket_id(), 0);
+ }
+ if (comp_dev->capa_mz == NULL) {
+ ZSDA_LOG(DEBUG, "Failed! comp_dev->capa_mz is NULL");
+ memset(&dev_info->comp_rte_dev, 0,
+ sizeof(dev_info->comp_rte_dev));
+ rte_compressdev_pmd_destroy(compressdev);
+ return -EFAULT;
+ }
+
+ memcpy(comp_dev->capa_mz->addr, capabilities, capa_size);
+ comp_dev->zsda_dev_capabilities = comp_dev->capa_mz->addr;
+
+ zsda_pci_dev->comp_dev = comp_dev;
+
+ return ZSDA_SUCCESS;
+}
+
+int
+zsda_comp_dev_destroy(struct zsda_pci_device *zsda_pci_dev)
+{
+ struct zsda_comp_dev_private *comp_dev;
+
+ if (zsda_pci_dev == NULL)
+ return -ENODEV;
+
+ comp_dev = zsda_pci_dev->comp_dev;
+ if (comp_dev == NULL)
+ return ZSDA_SUCCESS;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_memzone_free(zsda_pci_dev->comp_dev->capa_mz);
+
+ rte_compressdev_pmd_destroy(comp_dev->compressdev);
+ zsda_pci_dev->comp_dev = NULL;
+
+ return ZSDA_SUCCESS;
+}
new file mode 100644
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#ifndef _ZSDA_COMP_PMD_H_
+#define _ZSDA_COMP_PMD_H_
+
+#include <rte_compressdev_pmd.h>
+
+#include "zsda_qp.h"
+#include "zsda_device.h"
+
+/**< ZSDA Compression PMD driver name */
+#define COMPRESSDEV_NAME_ZSDA_PMD compress_zsda
+
+/** private data structure for a ZSDA compression device.
+ * This ZSDA device is a device offering only a compression service,
+ * there can be one of these on each zsda_pci_device (VF).
+ */
+struct zsda_comp_dev_private {
+ struct zsda_pci_device *zsda_pci_dev;
+ /**< The zsda pci device hosting the service */
+ struct rte_compressdev *compressdev;
+ /**< The pointer to this compression device structure */
+ const struct rte_compressdev_capabilities *zsda_dev_capabilities;
+ /* ZSDA device compression capabilities */
+ struct rte_mempool *xformpool;
+ /**< The device's pool for zsda_comp_xforms */
+ const struct rte_memzone *capa_mz;
+ /* Shared memzone for storing capabilities */
+};
+
+int zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev);
+
+int zsda_comp_dev_destroy(struct zsda_pci_device *zsda_pci_dev);
+
+#endif /* _ZSDA_COMP_PMD_H_ */