summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFiona Trahe <fiona.trahe@intel.com>2018-04-27 14:23:54 +0100
committerPablo de Lara <pablo.de.lara.guarch@intel.com>2018-05-10 17:46:19 +0100
commited7dd94f7f664b86d026ce6104b5a6b255a9b881 (patch)
tree92c4ae76ef86f336f554df1a6343e82df4a507e1
parent7b2491a62dcc4da2ad5afca2dbba458588126c23 (diff)
downloaddpdk-ed7dd94f7f66.zip
dpdk-ed7dd94f7f66.tar.gz
dpdk-ed7dd94f7f66.tar.xz
compressdev: add basic device management
Add basic functions to manage compress devices, including driver and device allocation, and the basic interface with compressdev PMDs. Signed-off-by: Fiona Trahe <fiona.trahe@intel.com> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com> Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com> Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
-rw-r--r--MAINTAINERS7
-rw-r--r--config/common_base6
-rw-r--r--config/rte_config.h3
-rw-r--r--doc/api/doxy-api-index.md1
-rw-r--r--doc/api/doxy-api.conf1
-rw-r--r--doc/guides/rel_notes/release_18_05.rst6
-rw-r--r--lib/Makefile3
-rw-r--r--lib/librte_compressdev/Makefile30
-rw-r--r--lib/librte_compressdev/meson.build10
-rw-r--r--lib/librte_compressdev/rte_compressdev.c378
-rw-r--r--lib/librte_compressdev/rte_compressdev.h169
-rw-r--r--lib/librte_compressdev/rte_compressdev_internal.h64
-rw-r--r--lib/librte_compressdev/rte_compressdev_pmd.c160
-rw-r--r--lib/librte_compressdev/rte_compressdev_pmd.h236
-rw-r--r--lib/librte_compressdev/rte_compressdev_version.map24
-rw-r--r--lib/meson.build2
-rw-r--r--mk/rte.app.mk1
17 files changed, 1100 insertions, 1 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 19811ec..f2221d1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -341,6 +341,13 @@ T: git://dpdk.org/next/dpdk-next-crypto
F: lib/librte_security/
F: doc/guides/prog_guide/rte_security.rst
+Compression API - EXPERIMENTAL
+M: Fiona Trahe <fiona.trahe@intel.com>
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+M: Ashish Gupta <ashish.gupta@caviumnetworks.com>
+T: git://dpdk.org/next/dpdk-next-crypto
+F: lib/librte_compressdev/
+
Eventdev API
M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
T: git://dpdk.org/next/dpdk-next-eventdev
diff --git a/config/common_base b/config/common_base
index de575d3..5ef4e52 100644
--- a/config/common_base
+++ b/config/common_base
@@ -570,6 +570,12 @@ CONFIG_RTE_LIBRTE_PMD_MVSAM_CRYPTO_DEBUG=n
CONFIG_RTE_LIBRTE_SECURITY=y
#
+# Compile generic compression device library
+#
+CONFIG_RTE_LIBRTE_COMPRESSDEV=y
+CONFIG_RTE_COMPRESS_MAX_DEVS=64
+
+#
# Compile generic event device library
#
CONFIG_RTE_LIBRTE_EVENTDEV=y
diff --git a/config/rte_config.h b/config/rte_config.h
index 04f6377..a1d0175 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -57,6 +57,9 @@
#define RTE_CRYPTO_MAX_DEVS 64
#define RTE_CRYPTODEV_NAME_LEN 64
+/* compressdev defines */
+#define RTE_COMPRESS_MAX_DEVS 64
+
/* eventdev defines */
#define RTE_EVENT_MAX_DEVS 16
#define RTE_EVENT_MAX_QUEUES_PER_DEV 64
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 3685e8e..8233e83 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -18,6 +18,7 @@ The public API headers are grouped by topics:
[bbdev] (@ref rte_bbdev.h),
[cryptodev] (@ref rte_cryptodev.h),
[security] (@ref rte_security.h),
+ [compressdev] (@ref rte_compressdev.h),
[eventdev] (@ref rte_eventdev.h),
[event_eth_rx_adapter] (@ref rte_event_eth_rx_adapter.h),
[event_timer_adapter] (@ref rte_event_timer_adapter.h),
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index aa66751..dfa4158 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -48,6 +48,7 @@ INPUT = doc/api/doxy-api-index.md \
lib/librte_cfgfile \
lib/librte_cmdline \
lib/librte_compat \
+ lib/librte_compressdev \
lib/librte_cryptodev \
lib/librte_distributor \
lib/librte_efd \
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index beccfa9..3fdfda8 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -139,6 +139,11 @@ New Features
* AES-CMAC (128-bit key).
+* **Added Compressdev Library, a generic compression service library.**
+
+ The compressdev library provides an API for offload of compression and
+ decompression operations to hardware or software accelerator devices.
+
* **Added the Event Timer Adapter Library.**
The Event Timer Adapter Library extends the event-based model by introducing
@@ -453,6 +458,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_cfgfile.so.2
librte_cmdline.so.2
+ librte_common_octeontx.so.1
+ + librte_compressdev.so.1
librte_cryptodev.so.4
librte_distributor.so.1
+ librte_eal.so.7
diff --git a/lib/Makefile b/lib/Makefile
index 02db127..c59f682 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -31,6 +31,9 @@ DIRS-$(CONFIG_RTE_LIBRTE_SECURITY) += librte_security
DEPDIRS-librte_security := librte_eal librte_mempool librte_ring librte_mbuf
DEPDIRS-librte_security += librte_ethdev
DEPDIRS-librte_security += librte_cryptodev
+DIRS-$(CONFIG_RTE_LIBRTE_COMPRESSDEV) += librte_compressdev
+DEPDIRS-librte_compressdev := librte_eal librte_mempool librte_ring librte_mbuf
+DEPDIRS-librte_compressdev += librte_kvargs
DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += librte_eventdev
DEPDIRS-librte_eventdev := librte_eal librte_ring librte_ethdev librte_hash \
librte_mempool librte_timer librte_cryptodev
diff --git a/lib/librte_compressdev/Makefile b/lib/librte_compressdev/Makefile
new file mode 100644
index 0000000..b847694
--- /dev/null
+++ b/lib/librte_compressdev/Makefile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017-2018 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_compressdev.a
+
+# library version
+LIBABIVER := 1
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+LDLIBS += -lrte_eal -lrte_mempool -lrte_kvargs
+
+# library source files
+SRCS-y += rte_compressdev.c rte_compressdev_pmd.c
+
+# export include files
+SYMLINK-y-include += rte_compressdev.h
+# export include files (for PMDs)
+SYMLINK-y-include += rte_compressdev_pmd.h
+SYMLINK-y-include += rte_compressdev_internal.h
+
+# versioning export map
+EXPORT_MAP := rte_compressdev_version.map
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_compressdev/meson.build b/lib/librte_compressdev/meson.build
new file mode 100644
index 0000000..895e959
--- /dev/null
+++ b/lib/librte_compressdev/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Intel Corporation
+
+allow_experimental_apis = true
+sources = files('rte_compressdev.c',
+ 'rte_compressdev_pmd.c')
+headers = files('rte_compressdev.h',
+ 'rte_compressdev_pmd.h',
+ 'rte_compressdev_internal.h')
+deps += ['kvargs', 'mbuf']
diff --git a/lib/librte_compressdev/rte_compressdev.c b/lib/librte_compressdev/rte_compressdev.c
new file mode 100644
index 0000000..751517c
--- /dev/null
+++ b/lib/librte_compressdev/rte_compressdev.c
@@ -0,0 +1,378 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <rte_malloc.h>
+#include <rte_eal.h>
+#include <rte_memzone.h>
+
+#include "rte_compressdev.h"
+#include "rte_compressdev_internal.h"
+#include "rte_compressdev_pmd.h"
+
+#define RTE_COMPRESSDEV_DETACHED (0)
+#define RTE_COMPRESSDEV_ATTACHED (1)
+
+struct rte_compressdev rte_comp_devices[RTE_COMPRESS_MAX_DEVS];
+
+struct rte_compressdev *rte_compressdevs = &rte_comp_devices[0];
+
+static struct rte_compressdev_global compressdev_globals = {
+ .devs = &rte_comp_devices[0],
+ .data = { NULL },
+ .nb_devs = 0,
+ .max_devs = RTE_COMPRESS_MAX_DEVS
+};
+
+struct rte_compressdev_global *rte_compressdev_globals = &compressdev_globals;
+
+static struct rte_compressdev *
+rte_compressdev_get_dev(uint8_t dev_id)
+{
+ return &rte_compressdev_globals->devs[dev_id];
+}
+
+struct rte_compressdev * __rte_experimental
+rte_compressdev_pmd_get_named_dev(const char *name)
+{
+ struct rte_compressdev *dev;
+ unsigned int i;
+
+ if (name == NULL)
+ return NULL;
+
+ for (i = 0; i < rte_compressdev_globals->max_devs; i++) {
+ dev = &rte_compressdev_globals->devs[i];
+
+ if ((dev->attached == RTE_COMPRESSDEV_ATTACHED) &&
+ (strcmp(dev->data->name, name) == 0))
+ return dev;
+ }
+
+ return NULL;
+}
+
+static unsigned int
+rte_compressdev_is_valid_dev(uint8_t dev_id)
+{
+ struct rte_compressdev *dev = NULL;
+
+ if (dev_id >= rte_compressdev_globals->nb_devs)
+ return 0;
+
+ dev = rte_compressdev_get_dev(dev_id);
+ if (dev->attached != RTE_COMPRESSDEV_ATTACHED)
+ return 0;
+ else
+ return 1;
+}
+
+
+uint8_t __rte_experimental
+rte_compressdev_count(void)
+{
+ return rte_compressdev_globals->nb_devs;
+}
+
+uint8_t __rte_experimental
+rte_compressdev_devices_get(const char *driver_name, uint8_t *devices,
+ uint8_t nb_devices)
+{
+ uint8_t i, count = 0;
+ struct rte_compressdev *devs = rte_compressdev_globals->devs;
+ uint8_t max_devs = rte_compressdev_globals->max_devs;
+
+ for (i = 0; i < max_devs && count < nb_devices; i++) {
+
+ if (devs[i].attached == RTE_COMPRESSDEV_ATTACHED) {
+ int cmp;
+
+ cmp = strncmp(devs[i].device->driver->name,
+ driver_name,
+ strlen(driver_name));
+
+ if (cmp == 0)
+ devices[count++] = devs[i].data->dev_id;
+ }
+ }
+
+ return count;
+}
+
+int __rte_experimental
+rte_compressdev_socket_id(uint8_t dev_id)
+{
+ struct rte_compressdev *dev;
+
+ if (!rte_compressdev_is_valid_dev(dev_id))
+ return -1;
+
+ dev = rte_compressdev_get_dev(dev_id);
+
+ return dev->data->socket_id;
+}
+
+static inline int
+rte_compressdev_data_alloc(uint8_t dev_id, struct rte_compressdev_data **data,
+ int socket_id)
+{
+ char mz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+ const struct rte_memzone *mz;
+ int n;
+
+ /* generate memzone name */
+ n = snprintf(mz_name, sizeof(mz_name),
+ "rte_compressdev_data_%u", dev_id);
+ if (n >= (int)sizeof(mz_name))
+ return -EINVAL;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ mz = rte_memzone_reserve(mz_name,
+ sizeof(struct rte_compressdev_data),
+ socket_id, 0);
+ } else
+ mz = rte_memzone_lookup(mz_name);
+
+ if (mz == NULL)
+ return -ENOMEM;
+
+ *data = mz->addr;
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ memset(*data, 0, sizeof(struct rte_compressdev_data));
+
+ return 0;
+}
+
+static uint8_t
+rte_compressdev_find_free_device_index(void)
+{
+ uint8_t dev_id;
+
+ for (dev_id = 0; dev_id < RTE_COMPRESS_MAX_DEVS; dev_id++) {
+ if (rte_comp_devices[dev_id].attached ==
+ RTE_COMPRESSDEV_DETACHED)
+ return dev_id;
+ }
+ return RTE_COMPRESS_MAX_DEVS;
+}
+
+struct rte_compressdev * __rte_experimental
+rte_compressdev_pmd_allocate(const char *name, int socket_id)
+{
+ struct rte_compressdev *compressdev;
+ uint8_t dev_id;
+
+ if (rte_compressdev_pmd_get_named_dev(name) != NULL) {
+ COMPRESSDEV_LOG(ERR,
+ "comp device with name %s already allocated!", name);
+ return NULL;
+ }
+
+ dev_id = rte_compressdev_find_free_device_index();
+ if (dev_id == RTE_COMPRESS_MAX_DEVS) {
+ COMPRESSDEV_LOG(ERR, "Reached maximum number of comp devices");
+ return NULL;
+ }
+ compressdev = rte_compressdev_get_dev(dev_id);
+
+ if (compressdev->data == NULL) {
+ struct rte_compressdev_data *compressdev_data =
+ compressdev_globals.data[dev_id];
+
+ int retval = rte_compressdev_data_alloc(dev_id,
+ &compressdev_data, socket_id);
+
+ if (retval < 0 || compressdev_data == NULL)
+ return NULL;
+
+ compressdev->data = compressdev_data;
+
+ snprintf(compressdev->data->name, RTE_COMPRESSDEV_NAME_MAX_LEN,
+ "%s", name);
+
+ compressdev->data->dev_id = dev_id;
+ compressdev->data->socket_id = socket_id;
+ compressdev->data->dev_started = 0;
+
+ compressdev->attached = RTE_COMPRESSDEV_ATTACHED;
+
+ compressdev_globals.nb_devs++;
+ }
+
+ return compressdev;
+}
+
+int __rte_experimental
+rte_compressdev_pmd_release_device(struct rte_compressdev *compressdev)
+{
+ int ret;
+
+ if (compressdev == NULL)
+ return -EINVAL;
+
+ /* Close device only if device operations have been set */
+ if (compressdev->dev_ops) {
+ ret = rte_compressdev_close(compressdev->data->dev_id);
+ if (ret < 0)
+ return ret;
+ }
+
+ compressdev->attached = RTE_COMPRESSDEV_DETACHED;
+ compressdev_globals.nb_devs--;
+ return 0;
+}
+
+int __rte_experimental
+rte_compressdev_configure(uint8_t dev_id, struct rte_compressdev_config *config)
+{
+ struct rte_compressdev *dev;
+
+ if (!rte_compressdev_is_valid_dev(dev_id)) {
+ COMPRESSDEV_LOG(ERR, "Invalid dev_id=%" PRIu8, dev_id);
+ return -EINVAL;
+ }
+
+ dev = &rte_comp_devices[dev_id];
+
+ if (dev->data->dev_started) {
+ COMPRESSDEV_LOG(ERR,
+ "device %d must be stopped to allow configuration", dev_id);
+ return -EBUSY;
+ }
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
+
+ return (*dev->dev_ops->dev_configure)(dev, config);
+}
+
+
+int __rte_experimental
+rte_compressdev_start(uint8_t dev_id)
+{
+ struct rte_compressdev *dev;
+ int diag;
+
+ COMPRESSDEV_LOG(DEBUG, "Start dev_id=%" PRIu8, dev_id);
+
+ if (!rte_compressdev_is_valid_dev(dev_id)) {
+ COMPRESSDEV_LOG(ERR, "Invalid dev_id=%" PRIu8, dev_id);
+ return -EINVAL;
+ }
+
+ dev = &rte_comp_devices[dev_id];
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
+
+ if (dev->data->dev_started != 0) {
+ COMPRESSDEV_LOG(ERR,
+ "Device with dev_id=%" PRIu8 " already started", dev_id);
+ return 0;
+ }
+
+ diag = (*dev->dev_ops->dev_start)(dev);
+ if (diag == 0)
+ dev->data->dev_started = 1;
+ else
+ return diag;
+
+ return 0;
+}
+
+void __rte_experimental
+rte_compressdev_stop(uint8_t dev_id)
+{
+ struct rte_compressdev *dev;
+
+ if (!rte_compressdev_is_valid_dev(dev_id)) {
+ COMPRESSDEV_LOG(ERR, "Invalid dev_id=%" PRIu8, dev_id);
+ return;
+ }
+
+ dev = &rte_comp_devices[dev_id];
+
+ RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
+
+ if (dev->data->dev_started == 0) {
+ COMPRESSDEV_LOG(ERR,
+ "Device with dev_id=%" PRIu8 " already stopped", dev_id);
+ return;
+ }
+
+ (*dev->dev_ops->dev_stop)(dev);
+ dev->data->dev_started = 0;
+}
+
+int __rte_experimental
+rte_compressdev_close(uint8_t dev_id)
+{
+ struct rte_compressdev *dev;
+ int retval;
+
+ if (!rte_compressdev_is_valid_dev(dev_id)) {
+ COMPRESSDEV_LOG(ERR, "Invalid dev_id=%" PRIu8, dev_id);
+ return -1;
+ }
+
+ dev = &rte_comp_devices[dev_id];
+
+ /* Device must be stopped before it can be closed */
+ if (dev->data->dev_started == 1) {
+ COMPRESSDEV_LOG(ERR, "Device %u must be stopped before closing",
+ dev_id);
+ return -EBUSY;
+ }
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
+ retval = (*dev->dev_ops->dev_close)(dev);
+
+ if (retval < 0)
+ return retval;
+
+ return 0;
+}
+
+void __rte_experimental
+rte_compressdev_info_get(uint8_t dev_id, struct rte_compressdev_info *dev_info)
+{
+ struct rte_compressdev *dev;
+
+ if (dev_id >= compressdev_globals.nb_devs) {
+ COMPRESSDEV_LOG(ERR, "Invalid dev_id=%d", dev_id);
+ return;
+ }
+
+ dev = &rte_comp_devices[dev_id];
+
+ memset(dev_info, 0, sizeof(struct rte_compressdev_info));
+
+ RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
+ (*dev->dev_ops->dev_infos_get)(dev, dev_info);
+
+ dev_info->driver_name = dev->device->driver->name;
+}
+
+const char * __rte_experimental
+rte_compressdev_name_get(uint8_t dev_id)
+{
+ struct rte_compressdev *dev = rte_compressdev_get_dev(dev_id);
+
+ if (dev == NULL)
+ return NULL;
+
+ return dev->data->name;
+}
+
+RTE_INIT(rte_compressdev_log);
+
+static void
+rte_compressdev_log(void)
+{
+ compressdev_logtype = rte_log_register("lib.compressdev");
+ if (compressdev_logtype >= 0)
+ rte_log_set_level(compressdev_logtype, RTE_LOG_NOTICE);
+}
diff --git a/lib/librte_compressdev/rte_compressdev.h b/lib/librte_compressdev/rte_compressdev.h
new file mode 100644
index 0000000..5be5973
--- /dev/null
+++ b/lib/librte_compressdev/rte_compressdev.h
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#ifndef _RTE_COMPRESSDEV_H_
+#define _RTE_COMPRESSDEV_H_
+
+/**
+ * @file rte_compressdev.h
+ *
+ * RTE Compression Device APIs
+ *
+ * Defines comp device APIs for the provisioning of compression operations.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+
+/** comp device information */
+struct rte_compressdev_info {
+ const char *driver_name; /**< Driver name. */
+};
+
+/**
+ * Get the compress device name given a device identifier.
+ *
+ * @param dev_id
+ * Compress device identifier
+ * @return
+ * - Returns compress device name.
+ * - Returns NULL if compress device is not present.
+ */
+const char * __rte_experimental
+rte_compressdev_name_get(uint8_t dev_id);
+
+/**
+ * Get the total number of compress devices that have been successfully
+ * initialised.
+ *
+ * @return
+ * - The total number of usable compress devices.
+ */
+uint8_t __rte_experimental
+rte_compressdev_count(void);
+
+/**
+ * Get number and identifiers of attached comp devices that
+ * use the same compress driver.
+ *
+ * @param driver_name
+ * Driver name
+ * @param devices
+ * Output devices identifiers
+ * @param nb_devices
+ * Maximal number of devices
+ *
+ * @return
+ * Returns number of attached compress devices.
+ */
+uint8_t __rte_experimental
+rte_compressdev_devices_get(const char *driver_name, uint8_t *devices,
+ uint8_t nb_devices);
+
+/*
+ * Return the NUMA socket to which a device is connected.
+ *
+ * @param dev_id
+ * Compress device identifier
+ * @return
+ * The NUMA socket id to which the device is connected or
+ * a default of zero if the socket could not be determined.
+ * -1 if returned is the dev_id value is out of range.
+ */
+int __rte_experimental
+rte_compressdev_socket_id(uint8_t dev_id);
+
+/** Compress device configuration structure */
+struct rte_compressdev_config {
+ int socket_id;
+};
+
+/**
+ * Configure a device.
+ *
+ * This function must be invoked first before any other function in the
+ * API. This function can also be re-invoked when a device is in the
+ * stopped state.
+ *
+ * @param dev_id
+ * Compress device identifier
+ * @param config
+ * The compress device configuration
+ * @return
+ * - 0: Success, device configured.
+ * - <0: Error code returned by the driver configuration function.
+ */
+int __rte_experimental
+rte_compressdev_configure(uint8_t dev_id,
+ struct rte_compressdev_config *config);
+
+/**
+ * Start a device.
+ *
+ * The device start step is called after configuring the device and setting up
+ * its queue pairs.
+ * On success, data-path functions exported by the API (enqueue/dequeue, etc)
+ * can be invoked.
+ *
+ * @param dev_id
+ * Compress device identifier
+ * @return
+ * - 0: Success, device started.
+ * - <0: Error code of the driver device start function.
+ */
+int __rte_experimental
+rte_compressdev_start(uint8_t dev_id);
+
+/**
+ * Stop a device. The device can be restarted with a call to
+ * rte_compressdev_start()
+ *
+ * @param dev_id
+ * Compress device identifier
+ */
+void __rte_experimental
+rte_compressdev_stop(uint8_t dev_id);
+
+/**
+ * Close an device.
+ * The memory allocated in the device gets freed.
+ * After calling this function, in order to use
+ * the device again, it is required to
+ * configure the device again.
+ *
+ * @param dev_id
+ * Compress device identifier
+ *
+ * @return
+ * - 0 on successfully closing device
+ * - <0 on failure to close device
+ */
+int __rte_experimental
+rte_compressdev_close(uint8_t dev_id);
+
+/**
+ * Retrieve the contextual information of a device.
+ *
+ * @param dev_id
+ * Compress device identifier
+ * @param dev_info
+ * A pointer to a structure of type *rte_compressdev_info*
+ * to be filled with the contextual information of the device
+ *
+ * @note The capabilities field of dev_info is set to point to the first
+ * element of an array of struct rte_compressdev_capabilities.
+ * The element after the last valid element has it's op field set to
+ * RTE_COMP_ALGO_LIST_END.
+ */
+void __rte_experimental
+rte_compressdev_info_get(uint8_t dev_id, struct rte_compressdev_info *dev_info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_COMPRESSDEV_H_ */
diff --git a/lib/librte_compressdev/rte_compressdev_internal.h b/lib/librte_compressdev/rte_compressdev_internal.h
new file mode 100644
index 0000000..0a2ddcb
--- /dev/null
+++ b/lib/librte_compressdev/rte_compressdev_internal.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#ifndef _RTE_COMPRESSDEV_INTERNAL_H_
+#define _RTE_COMPRESSDEV_INTERNAL_H_
+
+/* rte_compressdev_internal.h
+ * This file holds Compressdev private data structures.
+ */
+#include <rte_log.h>
+
+#define RTE_COMPRESSDEV_NAME_MAX_LEN (64)
+/**< Max length of name of comp PMD */
+
+/* Logging Macros */
+extern int compressdev_logtype;
+#define COMPRESSDEV_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, compressdev_logtype, "%s(): "fmt "\n", \
+ __func__, ##args)
+
+
+/** The data structure associated with each comp device. */
+struct rte_compressdev {
+ struct rte_compressdev_data *data;
+ /**< Pointer to device data */
+ struct rte_compressdev_ops *dev_ops;
+ /**< Functions exported by PMD */
+ uint64_t feature_flags;
+ /**< Supported features */
+ struct rte_device *device;
+ /**< Backing device */
+
+ uint8_t driver_id;
+ /**< comp driver identifier*/
+
+ __extension__
+ uint8_t attached : 1;
+ /**< Flag indicating the device is attached */
+} __rte_cache_aligned;
+
+/**
+ *
+ * The data part, with no function pointers, associated with each device.
+ *
+ * This structure is safe to place in shared memory to be common among
+ * different processes in a multi-process configuration.
+ */
+struct rte_compressdev_data {
+ uint8_t dev_id;
+ /**< Compress device identifier */
+ uint8_t socket_id;
+ /**< Socket identifier where memory is allocated */
+ char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+ /**< Unique identifier name */
+
+ __extension__
+ uint8_t dev_started : 1;
+ /**< Device state: STARTED(1)/STOPPED(0) */
+
+ void *dev_private;
+ /**< PMD-specific private data */
+} __rte_cache_aligned;
+#endif
diff --git a/lib/librte_compressdev/rte_compressdev_pmd.c b/lib/librte_compressdev/rte_compressdev_pmd.c
new file mode 100644
index 0000000..7de4f33
--- /dev/null
+++ b/lib/librte_compressdev/rte_compressdev_pmd.c
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#include <rte_malloc.h>
+#include <rte_kvargs.h>
+#include <rte_eal.h>
+
+#include "rte_compressdev_internal.h"
+#include "rte_compressdev_pmd.h"
+
+int compressdev_logtype;
+
+/**
+ * Parse name from argument
+ */
+static int
+rte_compressdev_pmd_parse_name_arg(const char *key __rte_unused,
+ const char *value, void *extra_args)
+{
+ struct rte_compressdev_pmd_init_params *params = extra_args;
+ int n;
+
+ n = snprintf(params->name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s", value);
+ if (n >= RTE_COMPRESSDEV_NAME_MAX_LEN)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * Parse unsigned integer from argument
+ */
+static int
+rte_compressdev_pmd_parse_uint_arg(const char *key __rte_unused,
+ const char *value, void *extra_args)
+{
+ int i;
+ char *end;
+
+ errno = 0;
+ i = strtol(value, &end, 10);
+ if (*end != 0 || errno != 0 || i < 0)
+ return -EINVAL;
+
+ *((uint32_t *)extra_args) = i;
+ return 0;
+}
+
+int __rte_experimental
+rte_compressdev_pmd_parse_input_args(
+ struct rte_compressdev_pmd_init_params *params,
+ const char *args)
+{
+ struct rte_kvargs *kvlist = NULL;
+ int ret = 0;
+
+ if (params == NULL)
+ return -EINVAL;
+
+ if (args) {
+ kvlist = rte_kvargs_parse(args, compressdev_pmd_valid_params);
+ if (kvlist == NULL)
+ return -EINVAL;
+
+ ret = rte_kvargs_process(kvlist,
+ RTE_COMPRESSDEV_PMD_SOCKET_ID_ARG,
+ &rte_compressdev_pmd_parse_uint_arg,
+ &params->socket_id);
+ if (ret < 0)
+ goto free_kvlist;
+
+ ret = rte_kvargs_process(kvlist,
+ RTE_COMPRESSDEV_PMD_NAME_ARG,
+ &rte_compressdev_pmd_parse_name_arg,
+ params);
+ if (ret < 0)
+ goto free_kvlist;
+ }
+
+free_kvlist:
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
+struct rte_compressdev * __rte_experimental
+rte_compressdev_pmd_create(const char *name,
+ struct rte_device *device,
+ size_t private_data_size,
+ struct rte_compressdev_pmd_init_params *params)
+{
+ struct rte_compressdev *compressdev;
+
+ if (params->name[0] != '\0') {
+ COMPRESSDEV_LOG(INFO, "[%s] User specified device name = %s\n",
+ device->driver->name, params->name);
+ name = params->name;
+ }
+
+ COMPRESSDEV_LOG(INFO, "[%s] - Creating compressdev %s\n",
+ device->driver->name, name);
+
+ COMPRESSDEV_LOG(INFO,
+ "[%s] - Init parameters - name: %s, socket id: %d",
+ device->driver->name, name,
+ params->socket_id);
+
+ /* allocate device structure */
+ compressdev = rte_compressdev_pmd_allocate(name, params->socket_id);
+ if (compressdev == NULL) {
+ COMPRESSDEV_LOG(ERR, "[%s] Failed to allocate comp device %s",
+ device->driver->name, name);
+ return NULL;
+ }
+
+ /* allocate private device structure */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ compressdev->data->dev_private =
+ rte_zmalloc_socket("compressdev device private",
+ private_data_size,
+ RTE_CACHE_LINE_SIZE,
+ params->socket_id);
+
+ if (compressdev->data->dev_private == NULL) {
+ COMPRESSDEV_LOG(ERR,
+ "[%s] Cannot allocate memory for compressdev %s private data",
+ device->driver->name, name);
+
+ rte_compressdev_pmd_release_device(compressdev);
+ return NULL;
+ }
+ }
+
+ compressdev->device = device;
+
+ return compressdev;
+}
+
+int __rte_experimental
+rte_compressdev_pmd_destroy(struct rte_compressdev *compressdev)
+{
+ int retval;
+
+ COMPRESSDEV_LOG(INFO, "[%s] Closing comp device %s",
+ compressdev->device->driver->name,
+ compressdev->device->name);
+
+ /* free comp device */
+ retval = rte_compressdev_pmd_release_device(compressdev);
+ if (retval)
+ return retval;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(compressdev->data->dev_private);
+
+ compressdev->device = NULL;
+ compressdev->data = NULL;
+
+ return 0;
+}
diff --git a/lib/librte_compressdev/rte_compressdev_pmd.h b/lib/librte_compressdev/rte_compressdev_pmd.h
new file mode 100644
index 0000000..43307ee
--- /dev/null
+++ b/lib/librte_compressdev/rte_compressdev_pmd.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#ifndef _RTE_COMPRESSDEV_PMD_H_
+#define _RTE_COMPRESSDEV_PMD_H_
+
+/** @file
+ * RTE comp PMD APIs
+ *
+ * @note
+ * These APIs are for comp PMDs only and user applications should not call
+ * them directly.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_common.h>
+
+#include "rte_compressdev.h"
+#include "rte_compressdev_internal.h"
+
+#define RTE_COMPRESSDEV_PMD_NAME_ARG ("name")
+#define RTE_COMPRESSDEV_PMD_SOCKET_ID_ARG ("socket_id")
+
+static const char * const compressdev_pmd_valid_params[] = {
+ RTE_COMPRESSDEV_PMD_NAME_ARG,
+ RTE_COMPRESSDEV_PMD_SOCKET_ID_ARG
+};
+
+/**
+ * @internal
+ * Initialisation parameters for comp devices
+ */
+struct rte_compressdev_pmd_init_params {
+ char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+ int socket_id;
+};
+
+/** Global structure used for maintaining state of allocated comp devices */
+struct rte_compressdev_global {
+ struct rte_compressdev *devs; /**< Device information array */
+ struct rte_compressdev_data *data[RTE_COMPRESS_MAX_DEVS];
+ /**< Device private data */
+ uint8_t nb_devs; /**< Number of devices found */
+ uint8_t max_devs; /**< Max number of devices */
+};
+
+/** Pointer to global array of comp devices */
+extern struct rte_compressdev *rte_compressdevs;
+/** Pointer to global comp devices data structure */
+extern struct rte_compressdev_global *rte_compressdev_globals;
+
+/**
+ * Get the rte_compressdev structure device pointer for the named device.
+ *
+ * @param name
+ * Compress device name
+ * @return
+ * - The rte_compressdev structure pointer for the given device identifier.
+ */
+struct rte_compressdev * __rte_experimental
+rte_compressdev_pmd_get_named_dev(const char *name);
+
+/**
+ * Definitions of all functions exported by a driver through the
+ * the generic structure of type *comp_dev_ops* supplied in the
+ * *rte_compressdev* structure associated with a device.
+ */
+
+/**
+ * Function used to configure device.
+ *
+ * @param dev
+ * Compress device
+ * @param config
+ * Compress device configurations
+ * @return
+ * Returns 0 on success
+ */
+typedef int (*compressdev_configure_t)(struct rte_compressdev *dev,
+ struct rte_compressdev_config *config);
+
+/**
+ * Function used to start a configured device.
+ *
+ * @param dev
+ * Compress device
+ * @return
+ * Returns 0 on success
+ */
+typedef int (*compressdev_start_t)(struct rte_compressdev *dev);
+
+/**
+ * Function used to stop a configured device.
+ *
+ * @param dev
+ * Compress device
+ */
+typedef void (*compressdev_stop_t)(struct rte_compressdev *dev);
+
+/**
+ * Function used to close a configured device.
+ *
+ * @param dev
+ * Compress device
+ * @return
+ * - 0 on success.
+ * - EAGAIN if can't close as device is busy
+ */
+typedef int (*compressdev_close_t)(struct rte_compressdev *dev);
+
+
+/**
+ * Function used to get specific information of a device.
+ *
+ * @param dev
+ * Compress device
+ */
+typedef void (*compressdev_info_get_t)(struct rte_compressdev *dev,
+ struct rte_compressdev_info *dev_info);
+
+/** comp device operations function pointer table */
+struct rte_compressdev_ops {
+ compressdev_configure_t dev_configure; /**< Configure device. */
+ compressdev_start_t dev_start; /**< Start device. */
+ compressdev_stop_t dev_stop; /**< Stop device. */
+ compressdev_close_t dev_close; /**< Close device. */
+
+ compressdev_info_get_t dev_infos_get; /**< Get device info. */
+};
+
+/**
+ * @internal
+ *
+ * Function for internal use by dummy drivers primarily, e.g. ring-based
+ * driver.
+ * Allocates a new compressdev slot for an comp device and returns the pointer
+ * to that slot for the driver to use.
+ *
+ * @param name
+ * Unique identifier name for each device
+ * @param socket_id
+ * Socket to allocate resources on
+ * @return
+ * - Slot in the rte_dev_devices array for a new device;
+ */
+struct rte_compressdev * __rte_experimental
+rte_compressdev_pmd_allocate(const char *name, int socket_id);
+
+/**
+ * @internal
+ *
+ * Function for internal use by dummy drivers primarily, e.g. ring-based
+ * driver.
+ * Release the specified compressdev device.
+ *
+ * @param dev
+ * Compress device
+ * @return
+ * - 0 on success, negative on error
+ */
+int __rte_experimental
+rte_compressdev_pmd_release_device(struct rte_compressdev *dev);
+
+
+/**
+ * @internal
+ *
+ * PMD assist function to parse initialisation arguments for comp driver
+ * when creating a new comp PMD device instance.
+ *
+ * PMD driver should set default values for that PMD before calling function,
+ * these default values will be over-written with successfully parsed values
+ * from args string.
+ *
+ * @param params
+ * Parsed PMD initialisation parameters
+ * @param args
+ * Input argument string to parse
+ * @return
+ * - 0 on success
+ * - errno on failure
+ */
+int __rte_experimental
+rte_compressdev_pmd_parse_input_args(
+ struct rte_compressdev_pmd_init_params *params,
+ const char *args);
+
+/**
+ * @internal
+ *
+ * PMD assist function to provide boiler plate code for comp driver to create
+ * and allocate resources for a new comp PMD device instance.
+ *
+ * @param name
+ * Compress device name
+ * @param device
+ * Base device instance
+ * @param params
+ * PMD initialisation parameters
+ * @return
+ * - comp device instance on success
+ * - NULL on creation failure
+ */
+struct rte_compressdev * __rte_experimental
+rte_compressdev_pmd_create(const char *name,
+ struct rte_device *device,
+ size_t private_data_size,
+ struct rte_compressdev_pmd_init_params *params);
+
+/**
+ * @internal
+ *
+ * PMD assist function to provide boiler plate code for comp driver to
+ * destroy and free resources associated with a comp PMD device instance.
+ *
+ * @param dev
+ * Compress device
+ * @return
+ * - 0 on success
+ * - errno on failure
+ */
+int __rte_experimental
+rte_compressdev_pmd_destroy(struct rte_compressdev *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_COMPRESSDEV_PMD_H_ */
diff --git a/lib/librte_compressdev/rte_compressdev_version.map b/lib/librte_compressdev/rte_compressdev_version.map
new file mode 100644
index 0000000..a996abc
--- /dev/null
+++ b/lib/librte_compressdev/rte_compressdev_version.map
@@ -0,0 +1,24 @@
+EXPERIMENTAL {
+ global:
+
+ rte_compressdev_callback_register;
+ rte_compressdev_callback_unregister;
+ rte_compressdev_close;
+ rte_compressdev_configure;
+ rte_compressdev_count;
+ rte_compressdev_devices_get;
+ rte_compressdev_info_get;
+ rte_compressdev_name_get;
+ rte_compressdev_pmd_allocate;
+ rte_compressdev_pmd_callback_process;
+ rte_compressdev_pmd_create;
+ rte_compressdev_pmd_destroy;
+ rte_compressdev_pmd_get_named_dev;
+ rte_compressdev_pmd_parse_input_args;
+ rte_compressdev_pmd_release_device;
+ rte_compressdev_socket_id;
+ rte_compressdev_start;
+ rte_compressdev_stop;
+
+ local: *;
+};
diff --git a/lib/meson.build b/lib/meson.build
index 166905c..0d55a64 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -14,7 +14,7 @@ libraries = [ 'compat', # just a header, used for versioning
'hash', # efd depends on this
'timer', # eventdev depends on this
'acl', 'bbdev', 'bitratestats', 'cfgfile',
- 'cmdline', 'cryptodev',
+ 'cmdline', 'compressdev', 'cryptodev',
'distributor', 'efd', 'eventdev',
'gro', 'gso', 'ip_frag', 'jobstats',
'kni', 'latencystats', 'lpm', 'member',
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 2a4769f..8ef5afb 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -95,6 +95,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER) += -lrte_ethdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_BBDEV) += -lrte_bbdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += -lrte_cryptodev
_LDLIBS-$(CONFIG_RTE_LIBRTE_SECURITY) += -lrte_security
+_LDLIBS-$(CONFIG_RTE_LIBRTE_COMPRESSDEV) += -lrte_compressdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += -lrte_eventdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_RAWDEV) += -lrte_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer