raw/common: introduce the Multi-function API
diff mbox series

Message ID 1584386504-17800-1-git-send-email-mairtin.oloingsigh@intel.com
State New
Delegated to: Thomas Monjalon
Headers show
Series
  • raw/common: introduce the Multi-function API
Related show

Checks

Context Check Description
ci/Intel-compilation fail Compilation issues
ci/iol-testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/checkpatch success coding style OK

Commit Message

Mairtin o Loingsigh March 16, 2020, 7:21 p.m. UTC
Multi-function API allows user to chain xforms of various
types together in a single operation

Signed-off-by: Mairtin o Loingsigh <mairtin.oloingsigh@intel.com>
---
 drivers/raw/Makefile                               |    1 +
 drivers/raw/common/Makefile                        |    8 +
 drivers/raw/common/multi_fn/Makefile               |   26 ++
 .../multi_fn/rte_common_multi_fn_version.map       |    8 +
 drivers/raw/common/multi_fn/rte_multi_fn.c         |   98 +++++++
 drivers/raw/common/multi_fn/rte_multi_fn.h         |  297 ++++++++++++++++++++
 mk/rte.app.mk                                      |    1 +
 7 files changed, 439 insertions(+), 0 deletions(-)
 create mode 100644 drivers/raw/common/Makefile
 create mode 100644 drivers/raw/common/multi_fn/Makefile
 create mode 100644 drivers/raw/common/multi_fn/rte_common_multi_fn_version.map
 create mode 100644 drivers/raw/common/multi_fn/rte_multi_fn.c
 create mode 100644 drivers/raw/common/multi_fn/rte_multi_fn.h

Comments

Thomas Monjalon April 1, 2020, 9:31 p.m. UTC | #1
Hi,

16/03/2020 20:21, Mairtin o Loingsigh:
> Multi-function API allows user to chain xforms of various
> types together in a single operation

Please could you elaborate a bit more?
Which problem are you trying to address?
What is the design?
How it can be used?

For such feature proposal, I recommend a design discussion
before starting the development.
Mairtin o Loingsigh April 2, 2020, 9:46 a.m. UTC | #2
Hi,

The purpose of the Multi-function API is to enable a broader set of transforms that aren't compression /crypto specific (CRC for example)
We had quite a few discussions on Multi-function in the mails below 

http://mails.dpdk.org/archives/dev/2020-February/157045.html
http://mails.dpdk.org/archives/dev/2020-March/159189.html

The v2 patchset will be ready for this in the coming days and we will include a cover-letter describing the feature and referencing back to the RFC discussion this time around

Regards,
Mairtin

-----Original Message-----
From: Thomas Monjalon <thomas@monjalon.net> 
Sent: Wednesday, April 1, 2020 10:31 PM
To: O'loingsigh, Mairtin <mairtin.oloingsigh@intel.com>
Cc: dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH] raw/common: introduce the Multi-function API

Hi,

16/03/2020 20:21, Mairtin o Loingsigh:
> Multi-function API allows user to chain xforms of various types 
> together in a single operation

Please could you elaborate a bit more?
Which problem are you trying to address?
What is the design?
How it can be used?

For such feature proposal, I recommend a design discussion before starting the development.
Thomas Monjalon April 2, 2020, 1 p.m. UTC | #3
Hi,

02/04/2020 11:46, O'loingsigh, Mairtin:
> From: Thomas Monjalon <thomas@monjalon.net> 
> > 16/03/2020 20:21, Mairtin o Loingsigh:
> > > Multi-function API allows user to chain xforms of various types
> > > together in a single operation
> > 
> > Please could you elaborate a bit more?
> > Which problem are you trying to address?
> > What is the design?
> > How it can be used?
> > 
> > For such feature proposal, I recommend a design discussion before starting
> > the development.
> 
> The purpose of the Multi-function API is to enable a broader set of
> transforms that aren't compression /crypto specific (CRC for example)
> We had quite a few discussions on Multi-function in the mails below 
> 
> http://mails.dpdk.org/archives/dev/2020-February/157045.html
> http://mails.dpdk.org/archives/dev/2020-March/159189.html

OK

Personally I did not have time yet to dive into this design.
But as a first impression, I feel it is not the right API.
DPDK is based on classes: ethdev, crypto, compress, baseband, regex
I want to understand why your features cannot fit in a class.


> The v2 patchset will be ready for this in the coming days
> and we will include a cover-letter describing the feature
> and referencing back to the RFC discussion this time around

I feel we will need a lot of time to discuss the design.
If you don't see any consensus on the design in the mailing list,
you should request an opinion from the Technical Board.

This feature is not a priority for 20.05 release.
By the way, it has not been announced in any roadmap.

Patch
diff mbox series

diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 80b043e..e16da8d 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -14,5 +14,6 @@  DIRS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV) += ioat
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_DMA_RAWDEV) += octeontx2_dma
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_EP_RAWDEV) += octeontx2_ep
+DIRS-y += common
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/common/Makefile b/drivers/raw/common/Makefile
new file mode 100644
index 0000000..26401de
--- /dev/null
+++ b/drivers/raw/common/Makefile
@@ -0,0 +1,8 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2020 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+DIRS-y += multi_fn
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/common/multi_fn/Makefile b/drivers/raw/common/multi_fn/Makefile
new file mode 100644
index 0000000..dbf61a6
--- /dev/null
+++ b/drivers/raw/common/multi_fn/Makefile
@@ -0,0 +1,26 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2020 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_multi_fn.a
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+# versioning export map
+EXPORT_MAP := rte_common_multi_fn_version.map
+
+# external library dependencies
+LDLIBS += -lrte_eal
+#LDLIBS += -lrte_rawdev
+#LDLIBS += -lrte_bus_vdev
+
+SRCS-y += rte_multi_fn.c
+
+SYMLINK-y-include += rte_multi_fn.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/common/multi_fn/rte_common_multi_fn_version.map b/drivers/raw/common/multi_fn/rte_common_multi_fn_version.map
new file mode 100644
index 0000000..8a22d01
--- /dev/null
+++ b/drivers/raw/common/multi_fn/rte_common_multi_fn_version.map
@@ -0,0 +1,8 @@ 
+EXPERIMENTAL {
+        global:
+
+	rte_multi_fn_session_create;
+	rte_multi_fn_session_destroy;
+
+        local: *;
+};
diff --git a/drivers/raw/common/multi_fn/rte_multi_fn.c b/drivers/raw/common/multi_fn/rte_multi_fn.c
new file mode 100644
index 0000000..51827c5
--- /dev/null
+++ b/drivers/raw/common/multi_fn/rte_multi_fn.c
@@ -0,0 +1,98 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <rte_string_fns.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_errno.h>
+
+#include "rte_rawdev.h"
+#include "rte_rawdev_pmd.h"
+#include "rte_multi_fn.h"
+
+/* Dynamic log identifier */
+static int librawmulti_fn_logtype;
+
+/* Logging Macros */
+#define MF_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, librawmulti_fn_logtype, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#define MF_ERR(fmt, args...) \
+	MF_LOG(ERR, fmt, ## args)
+#define MF_DEBUG(fmt, args...) \
+	MF_LOG(DEBUG, fmt, ## args)
+#define MF_INFO(fmt, args...) \
+	MF_LOG(INFO, fmt, ## args)
+
+struct rte_multi_fn_session *
+rte_multi_fn_session_create(uint16_t dev_id,
+				struct rte_rawdev_info *dev_info,
+				struct rte_multi_fn_xform *xform,
+				int socket_id)
+{
+	struct rte_rawdev *rawdev;
+	struct rte_multi_fn_device_info *dev_priv;
+
+	if (!rte_rawdev_pmd_is_valid_dev((dev_id))) {
+		MF_ERR("Invalid rawdev dev_id=%d", dev_id);
+		return NULL;
+	}
+
+	rawdev = &rte_rawdevs[dev_id];
+
+	dev_priv = dev_info->dev_private;
+
+	return dev_priv->create(rawdev, xform, socket_id);
+}
+
+int
+rte_multi_fn_session_destroy(uint16_t dev_id,
+				struct rte_rawdev_info *dev_info,
+				struct rte_multi_fn_session *sess)
+{
+	struct rte_rawdev *rawdev;
+	struct rte_multi_fn_device_info *dev_priv;
+
+	if (!rte_rawdev_pmd_is_valid_dev((dev_id))) {
+		MF_ERR("Invalid rawdev dev_id=%d", dev_id);
+		return -EINVAL;
+	}
+
+	rawdev = &rte_rawdevs[dev_id];
+
+	dev_priv = dev_info->dev_private;
+
+	return dev_priv->destroy(rawdev, sess);
+}
+
+RTE_INIT(libmulti_fn_dev_init_log)
+{
+	librawmulti_fn_logtype = rte_log_register("lib.multi_fn");
+	if (librawmulti_fn_logtype >= 0)
+		rte_log_set_level(librawmulti_fn_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/common/multi_fn/rte_multi_fn.h b/drivers/raw/common/multi_fn/rte_multi_fn.h
new file mode 100644
index 0000000..789d119
--- /dev/null
+++ b/drivers/raw/common/multi_fn/rte_multi_fn.h
@@ -0,0 +1,297 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation.
+ */
+
+#ifndef _RTE_MULTI_FN_H_
+#define _RTE_MULTI_FN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_compat.h>
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_comp.h>
+#include <rte_crypto.h>
+#include <rte_rawdev.h>
+
+/** Error Detection Algorithms */
+enum rte_multi_fn_err_detect_algorithm {
+	RTE_MULTI_FN_ERR_DETECT_CRC32_ETH,
+	/**< CRC32 Ethernet */
+	RTE_MULTI_FN_ERR_DETECT_BIP32
+	/**< BIP32 */
+};
+
+/** Error Detection Operation Types */
+enum rte_multi_fn_err_detect_operation {
+	RTE_MULTI_FN_ERR_DETECT_OP_VERIFY,
+	/**< Verify error detection result */
+	RTE_MULTI_FN_ERR_DETECT_OP_GENERATE
+	/**< Generate error detection result */
+};
+
+/** Error Detection Status */
+enum rte_multi_fn_err_detect_op_status {
+	RTE_MULTI_FN_ERR_DETECT_OP_STATUS_NOT_PROCESSED,
+	/**< Operation has not yet been processed by a device */
+	RTE_MULTI_FN_ERR_DETECT_OP_STATUS_SUCCESS,
+	/**< Operation completed successfully */
+	RTE_MULTI_FN_ERR_DETECT_OP_STATUS_VERIFY_FAILED,
+	/**< Verification failed */
+	RTE_MULTI_FN_ERR_DETECT_OP_STATUS_ERROR
+	/**< Error handling operation */
+};
+
+struct rte_multi_fn_err_detect_xform {
+	enum rte_multi_fn_err_detect_operation op;
+	/**< Error detection operation type */
+	enum rte_multi_fn_err_detect_algorithm algo;
+	/**< Error detection algorithm */
+	uint16_t err_detect_length;
+};
+
+/** Error Detection Operation */
+struct rte_multi_fn_err_detect_op {
+	struct rte_mbuf *m_src; /**< Source mbuf */
+	enum rte_multi_fn_err_detect_op_status status;
+	/**< Operation status */
+
+	struct {
+		uint16_t offset;
+		/**<
+		 * Starting point for error detection processing, specified
+		 * as the number of bytes from start of the packet in the
+		 * source mbuf
+		 */
+		uint16_t length;
+		/**<
+		 * The length, in bytes, of the source mbuf on which the error
+		 * detection operation will be computed
+		 */
+	} data; /**< Data offset and length for error detection */
+
+	struct {
+		uint8_t *data;
+		/**<
+		 * This points to the location where the error detection
+		 * result should be written (in the case of generation) or
+		 * where the purported result exists (in the case of
+		 * verification)
+		 *
+		 * The caller must ensure the required length of physically
+		 * contiguous memory is available at this address
+		 *
+		 * For a CRC, this may point into the mbuf packet data. For
+		 * an operation such as a BIP, this may point to a memory
+		 * location after the op
+		 *
+		 * For generation, the result will overwrite any data at this
+		 * location
+		 */
+		rte_iova_t phys_addr;
+		/**< Physical address of output data */
+	} output; /**< Output location */
+};
+
+/**
+ * Multi-function transform types
+ */
+enum rte_multi_fn_xform_type {
+	RTE_MULTI_FN_XFORM_TYPE_UNDEFINED,
+	/**< Undefined transform type */
+	RTE_MULTI_FN_XFORM_TYPE_CRYPTO_SYM,
+	/**< Symmetric crypto transform type */
+	RTE_MULTI_FN_XFORM_TYPE_CRYPTO_ASYM,
+	/**< Asymmetric crypto transform type */
+	RTE_MULTI_FN_XFORM_TYPE_COMP,
+	/**< Compression transform type */
+	RTE_MULTI_FN_XFORM_TYPE_ERR_DETECT
+	/**< Error detection transform type */
+};
+
+/**
+ * Multi-function transform setup data
+ *
+ * This structure is used to specify the multi-function transforms required.
+ * Multiple transforms can be chained together to specify a chain of transforms
+ * such as symmetric crypto followed by error detection, or compression followed
+ * by symmetric crypto. Each transform structure holds a single transform, with
+ * the type field specifying which transform is contained within the union.
+ */
+struct rte_multi_fn_xform {
+	struct rte_multi_fn_xform *next;
+	/**<
+	 * Next transform in the chain
+	 * - the last transform in the chain MUST set this to NULL
+	 */
+	enum rte_multi_fn_xform_type type;
+	/**< Transform type */
+
+	RTE_STD_C11
+	union {
+		struct rte_crypto_sym_xform crypto_sym;
+		/**< Symmetric crypto transform */
+		struct rte_crypto_asym_xform crypto_asym;
+		/**< Asymmetric crypto transform */
+		struct rte_comp_xform comp;
+		/**< Compression transform */
+		struct rte_multi_fn_err_detect_xform err_detect;
+		/**< Error detection transform */
+	};
+};
+
+/**
+ * Multi-function operation status
+ */
+enum rte_multi_fn_op_status {
+	RTE_MULTI_FN_OP_STATUS_SUCCESS = 0,
+	/**< Operation completed successfully */
+	RTE_MULTI_FN_OP_STATUS_FAILURE,
+	/**< Operation completed with failure */
+	RTE_MULTI_FN_STATUS_INVALID_SESSION,
+	/**< Operation failed due to invalid session arguments */
+	RTE_MULTI_FN_OP_STATUS_NOT_PROCESSED,
+	/**< Operation has not yet been processed by a device */
+};
+
+/**
+ * Multi-function session
+ */
+struct rte_multi_fn_session {
+	void *sess_private_data;
+};
+
+/**
+ * Operation data
+ */
+struct rte_multi_fn_op {
+	struct rte_multi_fn_op *next;
+	/**<
+	 * Next operation in the chain
+	 * - the last operation in the chain MUST set this to NULL
+	 */
+	struct rte_multi_fn_session *sess;
+	/**< Handle for the associated multi fn session */
+
+	struct rte_mempool *mempool;
+	/**< Mempool from which the operation is allocated */
+
+	struct rte_mbuf *m_src; /**< Source mbuf */
+	struct rte_mbuf *m_dst; /**< Destination mbuf */
+
+	enum rte_multi_fn_op_status overall_status;
+	/**<
+	 * Overall operation status
+	 * - indicates if all the operations in the chain succeeded or if any
+	 *   one of them failed
+	 */
+
+	uint8_t op_status;
+	/**<
+	 * Individual operation status
+	 * - indicates the status of the individual operation in the chain
+	 */
+
+	RTE_STD_C11
+	union {
+		struct rte_crypto_sym_op crypto_sym;
+		/**< Symmetric crypto operation */
+		struct rte_crypto_asym_op crypto_asym;
+		/**< Asymmetric crypto operation */
+		struct rte_comp_op comp;
+		/**< Compression operation */
+		struct rte_multi_fn_err_detect_op err_detect;
+		/**< Error detection operation */
+	};
+};
+
+/**<
+ * Typedef of session create function pointer
+ */
+typedef struct rte_multi_fn_session *(*session_create)(
+		struct rte_rawdev *rawdev,
+		struct rte_multi_fn_xform *,
+		int);
+
+/**<
+ * Typedef of session destroy function pointer
+ */
+typedef int (*session_destroy)(
+		struct rte_rawdev *rawdev,
+		struct rte_multi_fn_session *);
+
+/**<
+ * Structure containing session create and destroy function
+ * pointers and device configuration data.
+ */
+struct rte_multi_fn_device_info {
+	session_create create;
+	/**< Create session function pointer */
+	session_destroy destroy;
+	/**< Destroy session function pointer */
+	rte_rawdev_obj_t config;
+	/**< Device config info data pointer */
+};
+
+/**<
+ * Device configuration struct. Pass to rte_rawdev_configure()
+ */
+struct rte_multi_fn_dev_config {
+	uint16_t nb_queues; /**< Number of queue pairs to config */
+	unsigned int socket_id; /**< Socket to allocate queue on */
+};
+
+/**<
+ * Queue pair configuration struct. Passed to rte_rawdev_queue_setup()
+ */
+struct rte_multi_fn_qp_config {
+	uint32_t nb_descriptors; /**< Number of descriptors per queue pair */
+};
+
+/**
+ * Create multi-function session as specified by the transform chain
+ *
+ * @param   dev_id	The identifier of the device.
+ * @param   dev_info	Device info, obtained by calling rte_info_get()
+ * @param   xform	Pointer to the first element of the session transform
+ *			chain
+ * @param   socket_id	Socket to allocate the session on
+ *
+ * @return
+ *  - Pointer to session, if successful
+ *  - NULL, on failure
+ */
+__rte_experimental
+struct rte_multi_fn_session *
+rte_multi_fn_session_create(uint16_t dev_id,
+				struct rte_rawdev_info *dev_info,
+				struct rte_multi_fn_xform *xform,
+				int socket_id);
+
+/**
+ * Free memory associated with a multi-function session
+ *
+ * @param   dev_id	The identifier of the device.
+ * @param   dev_info	Device info, obtained by calling rte_info_get()
+ * @param   sess	Multi-function session to be freed
+ *
+ * @return
+ *  - 0, if successful
+ *  - -EINVAL, if session is NULL
+ *  - -EBUSY, if not all session data has been freed
+ */
+__rte_experimental
+int
+rte_multi_fn_session_destroy(uint16_t dev_id,
+				struct rte_rawdev_info *dev_info,
+				struct rte_multi_fn_session *sess);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_MULTI_FN_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d295ca0..117fe6a 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -98,6 +98,7 @@  _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RCU)            += -lrte_rcu
+_LDLIBS-y += -lrte_multi_fn
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUX),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni