DPDK patches and discussions
 help / color / mirror / Atom feed
From: Lee Daly <lee.daly@intel.com>
To: dev@dpdk.org
Cc: pablo.de.lara.guarch@intel.com, greg.b.tucker@intel.com,
	deepak.k.jain@intel.com, fiona.trahe@intel.com,
	Lee Daly <lee.daly@intel.com>
Subject: [dpdk-dev] [PATCH v4 04/10] compress/isal: add private xform related ops
Date: Sat, 28 Apr 2018 00:38:27 +0100	[thread overview]
Message-ID: <1524872313-196340-5-git-send-email-lee.daly@intel.com> (raw)
In-Reply-To: <1524872313-196340-1-git-send-email-lee.daly@intel.com>

This patch  creates, configures and frees the private xform, taking the
applications xform and using it to populate the PMDs own private xform
with the information which will be required for the compress/decompress
functions. This information includes the level, algorithm,
type of huffman code, type of checksum etc.

Signed-off-by: Lee Daly <lee.daly@intel.com>
---
 drivers/compress/isal/isal_compress_pmd.c         | 197 ++++++++++++++++++++++
 drivers/compress/isal/isal_compress_pmd_ops.c     | 103 ++++++++++-
 drivers/compress/isal/isal_compress_pmd_private.h |  15 ++
 3 files changed, 310 insertions(+), 5 deletions(-)

diff --git a/drivers/compress/isal/isal_compress_pmd.c b/drivers/compress/isal/isal_compress_pmd.c
index 5cc9409..325867b 100644
--- a/drivers/compress/isal/isal_compress_pmd.c
+++ b/drivers/compress/isal/isal_compress_pmd.c
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2018 Intel Corporation
  */
+#include <isa-l.h>
 
 #include <rte_bus_vdev.h>
 #include <rte_common.h>
@@ -9,8 +10,204 @@
 
 #include "isal_compress_pmd_private.h"
 
+#define RTE_COMP_ISAL_WINDOW_SIZE 15
+#define RTE_COMP_ISAL_LEVEL_ZERO 0 /* ISA-L Level 0 used for fixed Huffman */
+#define RTE_COMP_ISAL_LEVEL_ONE 1
+#define RTE_COMP_ISAL_LEVEL_TWO 2
+#define RTE_COMP_ISAL_LEVEL_THREE 3 /* Optimised for AVX512 & AVX2 only */
+
 int isal_logtype_driver;
 
+/* Verify and set private xform parameters */
+int
+isal_comp_set_priv_xform_parameters(struct isal_priv_xform *priv_xform,
+		const struct rte_comp_xform *xform)
+{
+	if (xform == NULL)
+		return -EINVAL;
+
+	/* Set compression private xform variables */
+	if (xform->type == RTE_COMP_COMPRESS) {
+		/* Set private xform type - COMPRESS/DECOMPRESS */
+		priv_xform->type = RTE_COMP_COMPRESS;
+
+		/* Set private xform algorithm */
+		if (xform->compress.algo != RTE_COMP_ALGO_DEFLATE) {
+			if (xform->compress.algo == RTE_COMP_ALGO_NULL) {
+				ISAL_PMD_LOG(ERR, "By-pass not supported\n");
+				return -ENOTSUP;
+			}
+			ISAL_PMD_LOG(ERR, "Algorithm not supported\n");
+			return -ENOTSUP;
+		}
+		priv_xform->compress.algo = RTE_COMP_ALGO_DEFLATE;
+
+		/* Set private xform checksum */
+		switch (xform->compress.chksum) {
+		case(RTE_COMP_CHECKSUM_NONE):
+			priv_xform->compress.chksum = RTE_COMP_CHECKSUM_NONE;
+			break;
+		case(RTE_COMP_CHECKSUM_ADLER32):
+			priv_xform->compress.chksum = IGZIP_ZLIB;
+			break;
+		case(RTE_COMP_CHECKSUM_CRC32):
+			priv_xform->compress.chksum = IGZIP_GZIP;
+			break;
+		default:
+			ISAL_PMD_LOG(ERR, "Checksum not supported\n");
+			return -ENOTSUP;
+		}
+
+		/* Set private xform window size, 32K supported */
+		if (xform->compress.window_size == RTE_COMP_ISAL_WINDOW_SIZE)
+			priv_xform->compress.window_size =
+					RTE_COMP_ISAL_WINDOW_SIZE;
+		else {
+			ISAL_PMD_LOG(ERR, "Window size not supported\n");
+			return -ENOTSUP;
+		}
+
+		/* Set private xform huffman type */
+		switch (xform->compress.deflate.huffman) {
+		case(RTE_COMP_HUFFMAN_DEFAULT):
+			priv_xform->compress.deflate.huffman =
+					RTE_COMP_HUFFMAN_DEFAULT;
+			break;
+		case(RTE_COMP_HUFFMAN_FIXED):
+			priv_xform->compress.deflate.huffman =
+					RTE_COMP_HUFFMAN_FIXED;
+			break;
+		case(RTE_COMP_HUFFMAN_DYNAMIC):
+			priv_xform->compress.deflate.huffman =
+					RTE_COMP_HUFFMAN_DYNAMIC;
+			break;
+		default:
+			ISAL_PMD_LOG(ERR, "Huffman code not supported\n");
+			return -ENOTSUP;
+		}
+
+		/* Set private xform level.
+		 * Checking compliance with compressdev API, -1 <= level => 9
+		 */
+		if (xform->compress.level < RTE_COMP_LEVEL_PMD_DEFAULT ||
+				xform->compress.level > RTE_COMP_LEVEL_MAX) {
+			ISAL_PMD_LOG(ERR, "Compression level out of range\n");
+			return -EINVAL;
+		}
+		/* Check for Compressdev API level 0, No compression
+		 * not supported in ISA-L
+		 */
+		else if (xform->compress.level == RTE_COMP_LEVEL_NONE) {
+			ISAL_PMD_LOG(ERR, "No Compression not supported\n");
+			return -ENOTSUP;
+		}
+		/* If using fixed huffman code, level must be 0 */
+		else if (priv_xform->compress.deflate.huffman ==
+				RTE_COMP_HUFFMAN_FIXED) {
+			ISAL_PMD_LOG(DEBUG, "ISA-L level 0 used due to a"
+					" fixed huffman code\n");
+			priv_xform->compress.level = RTE_COMP_ISAL_LEVEL_ZERO;
+			priv_xform->level_buffer_size =
+					ISAL_DEF_LVL0_DEFAULT;
+		} else {
+			/* Mapping API levels to ISA-L levels 1,2 & 3 */
+			switch (xform->compress.level) {
+			case RTE_COMP_LEVEL_PMD_DEFAULT:
+				/* Default is 1 if not using fixed huffman */
+				priv_xform->compress.level =
+						RTE_COMP_ISAL_LEVEL_ONE;
+				priv_xform->level_buffer_size =
+						ISAL_DEF_LVL1_DEFAULT;
+				break;
+			case RTE_COMP_LEVEL_MIN:
+				priv_xform->compress.level =
+						RTE_COMP_ISAL_LEVEL_ONE;
+				priv_xform->level_buffer_size =
+						ISAL_DEF_LVL1_DEFAULT;
+				break;
+			case RTE_COMP_ISAL_LEVEL_TWO:
+				priv_xform->compress.level =
+						RTE_COMP_ISAL_LEVEL_TWO;
+				priv_xform->level_buffer_size =
+						ISAL_DEF_LVL2_DEFAULT;
+				break;
+			/* Level 3 or higher requested */
+			default:
+				/* Check for AVX512, to use ISA-L level 3 */
+				if (rte_cpu_get_flag_enabled(
+						RTE_CPUFLAG_AVX512F)) {
+					priv_xform->compress.level =
+						RTE_COMP_ISAL_LEVEL_THREE;
+					priv_xform->level_buffer_size =
+						ISAL_DEF_LVL3_DEFAULT;
+				}
+				/* Check for AVX2, to use ISA-L level 3 */
+				else if (rte_cpu_get_flag_enabled(
+						RTE_CPUFLAG_AVX2)) {
+					priv_xform->compress.level =
+						RTE_COMP_ISAL_LEVEL_THREE;
+					priv_xform->level_buffer_size =
+						ISAL_DEF_LVL3_DEFAULT;
+				}
+				else{
+					ISAL_PMD_LOG(DEBUG, "Requested ISA-L level"
+						" 3 or above; Level 3 optimized"
+						" for AVX512 & AVX2 only."
+						" level changed to 2.\n");
+					priv_xform->compress.level =
+						RTE_COMP_ISAL_LEVEL_TWO;
+					priv_xform->level_buffer_size =
+						ISAL_DEF_LVL2_DEFAULT;
+				}
+			}
+		}
+	}
+
+	/* Set decompression private xform variables */
+	else if (xform->type == RTE_COMP_DECOMPRESS) {
+
+		/* Set private xform type - COMPRESS/DECOMPRESS */
+		priv_xform->type = RTE_COMP_DECOMPRESS;
+
+		/* Set private xform algorithm */
+		if (xform->decompress.algo != RTE_COMP_ALGO_DEFLATE) {
+			if (xform->decompress.algo == RTE_COMP_ALGO_NULL) {
+				ISAL_PMD_LOG(ERR, "By pass not supported\n");
+				return -ENOTSUP;
+			}
+			ISAL_PMD_LOG(ERR, "Algorithm not supported\n");
+			return -ENOTSUP;
+		}
+		priv_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE;
+
+		/* Set private xform checksum */
+		switch (xform->decompress.chksum) {
+		case(RTE_COMP_CHECKSUM_NONE):
+			priv_xform->decompress.chksum = RTE_COMP_CHECKSUM_NONE;
+			break;
+		case(RTE_COMP_CHECKSUM_ADLER32):
+			priv_xform->decompress.chksum = ISAL_ZLIB;
+			break;
+		case(RTE_COMP_CHECKSUM_CRC32):
+			priv_xform->decompress.chksum = ISAL_GZIP;
+			break;
+		default:
+			ISAL_PMD_LOG(ERR, "Checksum not supported\n");
+			return -ENOTSUP;
+		}
+
+		/* Set private xform window size, 32K supported */
+		if (xform->decompress.window_size == RTE_COMP_ISAL_WINDOW_SIZE)
+			priv_xform->decompress.window_size =
+					RTE_COMP_ISAL_WINDOW_SIZE;
+		else {
+			ISAL_PMD_LOG(ERR, "Window size not supported\n");
+			return -ENOTSUP;
+		}
+	}
+	return 0;
+}
+
 /* Create ISA-L compression device */
 static int
 compdev_isal_create(const char *name, struct rte_vdev_device *vdev,
diff --git a/drivers/compress/isal/isal_compress_pmd_ops.c b/drivers/compress/isal/isal_compress_pmd_ops.c
index 2f828c5..9c89df0 100644
--- a/drivers/compress/isal/isal_compress_pmd_ops.c
+++ b/drivers/compress/isal/isal_compress_pmd_ops.c
@@ -13,10 +13,59 @@ static const struct rte_compressdev_capabilities isal_pmd_capabilities[] = {
 
 /** Configure device */
 static int
-isal_comp_pmd_config(struct rte_compressdev *dev __rte_unused,
-		struct rte_compressdev_config *config __rte_unused)
+isal_comp_pmd_config(struct rte_compressdev *dev,
+		struct rte_compressdev_config *config)
 {
-	return 0;
+	int ret = 0;
+	unsigned int n;
+	char mp_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+	unsigned int elt_size = sizeof(struct isal_priv_xform);
+	struct isal_comp_private *internals = dev->data->dev_private;
+
+	n = snprintf(mp_name, sizeof(mp_name), "compdev_%d_xform_mp",
+			dev->data->dev_id);
+	if (n > sizeof(mp_name)) {
+		ISAL_PMD_LOG(ERR,
+			"Unable to create unique name for xform mempool");
+		return -ENOMEM;
+	}
+
+	internals->priv_xform_mp = rte_mempool_lookup(mp_name);
+
+	if (internals->priv_xform_mp != NULL) {
+		if (((internals->priv_xform_mp)->elt_size != elt_size) ||
+				((internals->priv_xform_mp)->size <
+					config->max_nb_priv_xforms)) {
+
+			ISAL_PMD_LOG(ERR, "%s mempool already exists with different"
+				" initialization parameters", mp_name);
+			internals->priv_xform_mp = NULL;
+			return -ENOMEM;
+		}
+	} else { /* First time configuration */
+		internals->priv_xform_mp = rte_mempool_create(
+				mp_name, /* mempool name */
+				/* number of elements*/
+				config->max_nb_priv_xforms,
+				elt_size, /* element size*/
+				0, /* Cache size*/
+				0, /* private data size */
+				NULL, /* obj initialization constructor */
+				NULL, /* obj initialization constructor arg */
+				NULL, /**< obj constructor*/
+				NULL, /* obj constructor arg */
+				config->socket_id, /* socket id */
+				0); /* flags */
+	}
+
+	if (internals->priv_xform_mp == NULL) {
+		ISAL_PMD_LOG(ERR, "%s mempool allocation failed", mp_name);
+		return -ENOMEM;
+	}
+
+	dev->data->dev_private = internals;
+
+	return ret;
 }
 
 /** Start device */
@@ -57,6 +106,50 @@ isal_comp_pmd_info_get(struct rte_compressdev *dev __rte_unused,
 	}
 }
 
+/** Set private xform data*/
+static int
+isal_comp_pmd_priv_xform_create(struct rte_compressdev *dev,
+			const struct rte_comp_xform *xform, void **priv_xform)
+{
+	int ret;
+	struct isal_comp_private *internals = dev->data->dev_private;
+
+	if (xform == NULL) {
+		ISAL_PMD_LOG(ERR, "Invalid Xform struct");
+		return -EINVAL;
+	}
+
+	if (rte_mempool_get(internals->priv_xform_mp, priv_xform)) {
+		ISAL_PMD_LOG(ERR,
+			"Couldn't get object from private xform mempool");
+		return -ENOMEM;
+	}
+
+	ret = isal_comp_set_priv_xform_parameters(*priv_xform, xform);
+	if (ret != 0) {
+		ISAL_PMD_LOG(ERR, "Failed to configure private xform parameters");
+
+		/* Return private xform to mempool */
+		rte_mempool_put(internals->priv_xform_mp, priv_xform);
+		return ret;
+	}
+	return 0;
+}
+
+/** Clear memory of the private xform so it doesn't leave key material behind */
+static int
+isal_comp_pmd_priv_xform_free(struct rte_compressdev *dev, void *priv_xform)
+{
+	struct isal_comp_private *internals = dev->data->dev_private;
+
+	/* Zero out the whole structure */
+	if (priv_xform) {
+		memset(priv_xform, 0, sizeof(struct isal_priv_xform));
+		rte_mempool_put(internals->priv_xform_mp, priv_xform);
+	}
+	return 0;
+}
+
 struct rte_compressdev_ops isal_pmd_ops = {
 		.dev_configure		= isal_comp_pmd_config,
 		.dev_start		= isal_comp_pmd_start,
@@ -71,8 +164,8 @@ struct rte_compressdev_ops isal_pmd_ops = {
 		.queue_pair_setup	= NULL,
 		.queue_pair_release	= NULL,
 
-		.private_xform_create	= NULL,
-		.private_xform_free	= NULL,
+		.private_xform_create	= isal_comp_pmd_priv_xform_create,
+		.private_xform_free	= isal_comp_pmd_priv_xform_free,
 };
 
 struct rte_compressdev_ops *isal_compress_pmd_ops = &isal_pmd_ops;
diff --git a/drivers/compress/isal/isal_compress_pmd_private.h b/drivers/compress/isal/isal_compress_pmd_private.h
index efbe68b..7e3b840 100644
--- a/drivers/compress/isal/isal_compress_pmd_private.h
+++ b/drivers/compress/isal/isal_compress_pmd_private.h
@@ -30,6 +30,21 @@ struct isal_comp_qp {
 	uint16_t num_free_elements;
 } __rte_cache_aligned;
 
+/** ISA-L private xform structure */
+struct isal_priv_xform {
+	enum rte_comp_xform_type type;
+	union {
+		struct rte_comp_compress_xform compress;
+		struct rte_comp_decompress_xform decompress;
+	};
+	uint32_t level_buffer_size;
+} __rte_cache_aligned;
+
+/** Set and validate NULL comp private xform parameters */
+extern int
+isal_comp_set_priv_xform_parameters(struct isal_priv_xform *priv_xform,
+			const struct rte_comp_xform *xform);
+
 /** device specific operations function pointer structure */
 extern struct rte_compressdev_ops *isal_compress_pmd_ops;
 
-- 
2.7.4

  parent reply	other threads:[~2018-04-27 23:39 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-09 16:50 [dpdk-dev] [PATCH] compress/isal: ISA-L compression PMD Lee Daly
2018-04-06 18:13 ` [dpdk-dev] [PATCH v2] " Lee Daly
2018-04-17 13:35   ` [dpdk-dev] [PATCH v3 00/11] add " Lee Daly
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 01/11] compress/isal: add skeleton " Lee Daly
2018-04-24  8:56       ` De Lara Guarch, Pablo
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 02/11] compress/isal: add pmd device init and de-init Lee Daly
2018-04-24  9:21       ` De Lara Guarch, Pablo
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 03/11] compress/isal: add basic pmd ops Lee Daly
2018-04-24  9:28       ` De Lara Guarch, Pablo
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 04/11] compress/isal: add private xform related ops Lee Daly
2018-04-24  9:45       ` De Lara Guarch, Pablo
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 05/11] compress/isal: add queue pair " Lee Daly
2018-04-24  9:56       ` De Lara Guarch, Pablo
2018-04-26 16:44         ` Daly, Lee
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 06/11] compress/isal: support enqueue/dequeue api Lee Daly
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 07/11] compress/isal: add stats related ops Lee Daly
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 08/11] compress/isal: add ISA-L compression functionality Lee Daly
2018-04-24 10:05       ` De Lara Guarch, Pablo
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 09/11] compress/isal: add ISA-L decomp functionality Lee Daly
2018-04-24 10:09       ` De Lara Guarch, Pablo
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 10/11] compress/isal: add generic compression driver docs Lee Daly
2018-04-23 14:47       ` Kovacevic, Marko
2018-04-24 10:47       ` De Lara Guarch, Pablo
2018-04-24 11:06       ` De Lara Guarch, Pablo
2018-04-25 14:25         ` Daly, Lee
2018-04-17 13:35     ` [dpdk-dev] [PATCH v3 11/11] compress/isal: add ISA-L compression PMD docs Lee Daly
2018-04-23 14:53       ` Kovacevic, Marko
2018-04-23 15:33       ` Kovacevic, Marko
2018-04-23 15:51         ` Daly, Lee
2018-04-24 11:04       ` De Lara Guarch, Pablo
2018-04-27 23:38       ` [dpdk-dev] [PATCH v4 00/10] add ISA-L compression PMD Lee Daly
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 01/10] compress/isal: add skeleton " Lee Daly
2018-05-08 12:32           ` [dpdk-dev] [PATCH v5 00/10] add " Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 01/10] compress/isal: add skeleton " Lee Daly
2018-05-09 16:14               ` [dpdk-dev] [PATCH v6 00/10] add " Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 01/10] compress/isal: add skeleton " Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 02/10] compress/isal: add pmd device init and de-init Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 03/10] compress/isal: add basic pmd ops Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 04/10] compress/isal: add private xform related ops Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 05/10] compress/isal: add queue pair " Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 06/10] compress/isal: support enqueue/dequeue api Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 07/10] compress/isal: add stats related ops Lee Daly
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 08/10] compress/isal: add ISA-L compression functionality Lee Daly
2018-05-09 17:39                   ` Tucker, Greg B
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 09/10] compress/isal: add ISA-L decomp functionality Lee Daly
2018-05-09 17:41                   ` Tucker, Greg B
2018-05-09 16:14                 ` [dpdk-dev] [PATCH v6 10/10] doc: add compression driver and ISA-L PMD docs Lee Daly
2018-05-09 20:56                 ` [dpdk-dev] [PATCH v6 00/10] add ISA-L compression PMD De Lara Guarch, Pablo
2018-05-09 21:36                   ` De Lara Guarch, Pablo
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 02/10] compress/isal: add pmd device init and de-init Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 03/10] compress/isal: add basic pmd ops Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 04/10] compress/isal: add private xform related ops Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 05/10] compress/isal: add queue pair " Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 06/10] compress/isal: support enqueue/dequeue api Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 07/10] compress/isal: add stats related ops Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 08/10] compress/isal: add ISA-L compression functionality Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 09/10] compress/isal: add ISA-L decomp functionality Lee Daly
2018-05-08 12:32             ` [dpdk-dev] [PATCH v5 10/10] doc: add compression driver and ISA-L PMD docs Lee Daly
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 02/10] compress/isal: add pmd device init and de-init Lee Daly
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 03/10] compress/isal: add basic pmd ops Lee Daly
2018-04-27 23:38         ` Lee Daly [this message]
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 05/10] compress/isal: add queue pair related ops Lee Daly
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 06/10] compress/isal: support enqueue/dequeue api Lee Daly
2018-05-03 21:46           ` De Lara Guarch, Pablo
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 07/10] compress/isal: add stats related ops Lee Daly
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 08/10] compress/isal: add ISA-L compression functionality Lee Daly
2018-05-03 21:37           ` De Lara Guarch, Pablo
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 09/10] compress/isal: add ISA-L decomp functionality Lee Daly
2018-04-27 23:38         ` [dpdk-dev] [PATCH v4 10/10] doc: add compression driver and ISA-L PMD docs Lee Daly
2018-05-03 21:49           ` De Lara Guarch, Pablo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1524872313-196340-5-git-send-email-lee.daly@intel.com \
    --to=lee.daly@intel.com \
    --cc=deepak.k.jain@intel.com \
    --cc=dev@dpdk.org \
    --cc=fiona.trahe@intel.com \
    --cc=greg.b.tucker@intel.com \
    --cc=pablo.de.lara.guarch@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).