compressdev: add basic device management
authorFiona Trahe <fiona.trahe@intel.com>
Fri, 27 Apr 2018 13:23:54 +0000 (14:23 +0100)
committerPablo de Lara <pablo.de.lara.guarch@intel.com>
Thu, 10 May 2018 16:46:19 +0000 (17:46 +0100)
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>
17 files changed:
MAINTAINERS
config/common_base
config/rte_config.h
doc/api/doxy-api-index.md
doc/api/doxy-api.conf
doc/guides/rel_notes/release_18_05.rst
lib/Makefile
lib/librte_compressdev/Makefile [new file with mode: 0644]
lib/librte_compressdev/meson.build [new file with mode: 0644]
lib/librte_compressdev/rte_compressdev.c [new file with mode: 0644]
lib/librte_compressdev/rte_compressdev.h [new file with mode: 0644]
lib/librte_compressdev/rte_compressdev_internal.h [new file with mode: 0644]
lib/librte_compressdev/rte_compressdev_pmd.c [new file with mode: 0644]
lib/librte_compressdev/rte_compressdev_pmd.h [new file with mode: 0644]
lib/librte_compressdev/rte_compressdev_version.map [new file with mode: 0644]
lib/meson.build
mk/rte.app.mk

index 19811ec..f2221d1 100644 (file)
@@ -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
index de575d3..5ef4e52 100644 (file)
@@ -569,6 +569,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
 #
index 04f6377..a1d0175 100644 (file)
@@ -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
index 3685e8e..8233e83 100644 (file)
@@ -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),
index aa66751..dfa4158 100644 (file)
@@ -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 \
index beccfa9..3fdfda8 100644 (file)
@@ -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
index 02db127..c59f682 100644 (file)
@@ -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 (file)
index 0000000..b847694
--- /dev/null
@@ -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 (file)
index 0000000..895e959
--- /dev/null
@@ -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 (file)
index 0000000..751517c
--- /dev/null
@@ -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 (file)
index 0000000..5be5973
--- /dev/null
@@ -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 (file)
index 0000000..0a2ddcb
--- /dev/null
@@ -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 (file)
index 0000000..7de4f33
--- /dev/null
@@ -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 (file)
index 0000000..43307ee
--- /dev/null
@@ -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 (file)
index 0000000..a996abc
--- /dev/null
@@ -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: *;
+};
index 166905c..0d55a64 100644 (file)
@@ -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',
index 2a4769f..8ef5afb 100644 (file)
@@ -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