All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lee Daly <lee.daly@intel.com>
To: pablo.de.lara.guarch@intel.com
Cc: dev@dpdk.org, Lee Daly <lee.daly@intel.com>
Subject: [PATCH] compress/isal: add chained mbuf support
Date: Thu,  5 Jul 2018 12:03:34 +0100	[thread overview]
Message-ID: <1530788614-192928-1-git-send-email-lee.daly@intel.com> (raw)

This patch adds chained mbuf support for input or output buffers
during compression/decompression operations.

Signed-off-by: Lee Daly <lee.daly@intel.com>
---
 doc/guides/compressdevs/features/isal.ini     |   2 +-
 doc/guides/compressdevs/isal.rst              |   2 -
 drivers/compress/isal/isal_compress_pmd.c     | 224 +++++++++++++++++++++-----
 drivers/compress/isal/isal_compress_pmd_ops.c |   3 +-
 4 files changed, 187 insertions(+), 44 deletions(-)

diff --git a/doc/guides/compressdevs/features/isal.ini b/doc/guides/compressdevs/features/isal.ini
index ad2718d..0966e69 100644
--- a/doc/guides/compressdevs/features/isal.ini
+++ b/doc/guides/compressdevs/features/isal.ini
@@ -12,7 +12,7 @@ CPU AVX512     = Y
 CPU NEON       =
 Stateful       =
 By-Pass        =
-Chained mbufs  =
+Chained mbufs  = Y
 Deflate        = Y
 LZS            =
 Adler32        =
diff --git a/doc/guides/compressdevs/isal.rst b/doc/guides/compressdevs/isal.rst
index 276ff06..3bc3022 100644
--- a/doc/guides/compressdevs/isal.rst
+++ b/doc/guides/compressdevs/isal.rst
@@ -78,8 +78,6 @@ As a result the level mappings from the API to the PMD are shown below.
 Limitations
 -----------
 
-* Chained mbufs will not be supported until a future release, meaning max data size being passed to PMD through a single mbuf is 64K - 1. If data is larger than this it will need to be split up and sent as multiple operations.
-
 * Compressdev level 0, no compression, is not supported.
 
 * Checksums will not be supported until future release.
diff --git a/drivers/compress/isal/isal_compress_pmd.c b/drivers/compress/isal/isal_compress_pmd.c
index 0f025a3..1ec2d98 100644
--- a/drivers/compress/isal/isal_compress_pmd.c
+++ b/drivers/compress/isal/isal_compress_pmd.c
@@ -188,6 +188,120 @@ isal_comp_set_priv_xform_parameters(struct isal_priv_xform *priv_xform,
 	return 0;
 }
 
+/* Compression using chained mbufs for input/output data */
+static int
+chained_mbuf_compression(struct rte_comp_op *op, struct isal_comp_qp *qp)
+{
+	int ret;
+	uint32_t consumed_data;
+	uint32_t remaining_data = op->src.length;
+	struct rte_mbuf *src = op->m_src;
+	struct rte_mbuf *dst = op->m_dst;
+
+	qp->stream->avail_in = src->data_len;
+	while (qp->stream->internal_state.state != ZSTATE_END) {
+		/* Last segment of data */
+		if (remaining_data <= src->data_len)
+			qp->stream->end_of_stream = 1;
+
+		/* Execute compression operation */
+		ret = isal_deflate(qp->stream);
+		op->produced = qp->stream->total_out;
+		consumed_data = src->data_len - qp->stream->avail_in;
+		remaining_data -= consumed_data;
+
+		if (ret != COMP_OK) {
+			op->status = RTE_COMP_OP_STATUS_ERROR;
+			return ret;
+		}
+
+		if (qp->stream->avail_in == 0 &&
+				qp->stream->total_in != op->src.length) {
+			if (src->next != NULL) {
+				src = src->next;
+				qp->stream->next_in =
+						rte_pktmbuf_mtod(src, uint8_t *);
+				qp->stream->avail_in =
+					RTE_MIN(remaining_data, src->data_len);
+			}
+		}
+
+		if (qp->stream->avail_out == 0 &&
+				qp->stream->internal_state.state != ZSTATE_END) {
+			if (dst->next != NULL) {
+				dst = dst->next;
+				qp->stream->next_out =
+						rte_pktmbuf_mtod(dst, uint8_t *);
+				qp->stream->avail_out = dst->data_len;
+			} else {
+				ISAL_PMD_LOG(ERR,
+				"Not enough output buffer segments\n"
+					"Output Produced: %d\n", op->produced);
+				op->status =
+				RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
+				return -1;
+			}
+		}
+	}
+	op->consumed = qp->stream->total_in;
+
+	return 0;
+}
+
+/* Decompression using chained mbufs for input/output data */
+static int
+chained_mbuf_decompression(struct rte_comp_op *op, struct isal_comp_qp *qp)
+{
+	int ret;
+	uint32_t consumed_data;
+	uint32_t remaining_data = op->src.length;
+	struct rte_mbuf *src = op->m_src;
+	struct rte_mbuf *dst = op->m_dst;
+
+	qp->state->avail_in = src->data_len;
+	while (qp->state->block_state != ISAL_BLOCK_FINISH) {
+
+		ret = isal_inflate(qp->state);
+		op->produced = qp->state->total_out;
+		consumed_data = src->data_len - qp->state->avail_in;
+		op->consumed += consumed_data;
+		remaining_data -= consumed_data;
+
+		if (ret != ISAL_DECOMP_OK) {
+			op->status = RTE_COMP_OP_STATUS_ERROR;
+			return ret;
+		}
+
+		if (qp->state->avail_in == 0 &&
+				op->consumed != op->src.length) {
+			if (src->next != NULL) {
+				src = src->next;
+				qp->state->next_in =
+						rte_pktmbuf_mtod(src, uint8_t *);
+				qp->state->avail_in =
+					RTE_MIN(remaining_data, src->data_len);
+			}
+		}
+
+		if (qp->state->avail_out == 0) {
+			if (dst->next != NULL) {
+				dst = dst->next;
+				qp->state->next_out =
+						rte_pktmbuf_mtod(dst, uint8_t *);
+				qp->state->avail_out = dst->data_len;
+			} else {
+				ISAL_PMD_LOG(ERR,
+				"Not enough output buffer segments\n");
+				op->status =
+				RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
 /* Stateless Compression Function */
 static int
 process_isal_deflate(struct rte_comp_op *op, struct isal_comp_qp *qp,
@@ -212,11 +326,9 @@ process_isal_deflate(struct rte_comp_op *op, struct isal_comp_qp *qp,
 	qp->stream->level_buf_size = priv_xform->level_buffer_size;
 
 	/* Point compression stream structure to input/output buffers */
-	qp->stream->avail_in = op->src.length;
 	qp->stream->next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *);
 	qp->stream->avail_out = op->m_dst->data_len;
 	qp->stream->next_out  = rte_pktmbuf_mtod(op->m_dst, uint8_t *);
-	qp->stream->end_of_stream = 1; /* All input consumed in one go */
 
 	if (unlikely(!qp->stream->next_in || !qp->stream->next_out)) {
 		ISAL_PMD_LOG(ERR, "Invalid source or destination buffers\n");
@@ -224,6 +336,12 @@ process_isal_deflate(struct rte_comp_op *op, struct isal_comp_qp *qp,
 		return -1;
 	}
 
+	if (op->m_src->pkt_len < op->src.length) {
+		ISAL_PMD_LOG(ERR, "Input mbuf(s) not big enough.\n");
+		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
+		return -1;
+	}
+
 	/* Set op huffman code */
 	if (priv_xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_FIXED)
 		isal_deflate_set_hufftables(qp->stream, NULL,
@@ -238,30 +356,43 @@ process_isal_deflate(struct rte_comp_op *op, struct isal_comp_qp *qp,
 		isal_deflate_set_hufftables(qp->stream, NULL,
 				IGZIP_HUFFTABLE_DEFAULT);
 
-	/* Execute compression operation */
-	ret =  isal_deflate_stateless(qp->stream);
 
-	/* Check that output buffer did not run out of space */
-	if (ret == STATELESS_OVERFLOW) {
-		ISAL_PMD_LOG(ERR, "Output buffer not big enough\n");
-		op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
-		return ret;
-	}
+	/* Chained mbuf input/output */
+	if (op->m_src->nb_segs > 1 || op->m_dst->nb_segs > 1) {
+		ret = chained_mbuf_compression(op, qp);
+		if (ret < 0)
+			return ret;
+	} else {
+		/* All input consumed in one go */
+		qp->stream->end_of_stream = 1;
+		qp->stream->avail_in = op->src.length;
+
+		/* Execute compression operation */
+		ret =  isal_deflate_stateless(qp->stream);
+
+		/* Check that output buffer did not run out of space */
+		if (ret == STATELESS_OVERFLOW) {
+			ISAL_PMD_LOG(ERR, "Output buffer not big enough\n");
+			op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
+			return ret;
+		}
 
-	/* Check that input buffer has been fully consumed */
-	if (qp->stream->avail_in != (uint32_t)0) {
-		ISAL_PMD_LOG(ERR, "Input buffer could not be read entirely\n");
-		op->status = RTE_COMP_OP_STATUS_ERROR;
-		return -1;
-	}
+		/* Check that input buffer has been fully consumed */
+		if (qp->stream->avail_in != (uint32_t)0) {
+			ISAL_PMD_LOG(ERR,
+		"Input buffer could not be read entirely\n");
+			op->status = RTE_COMP_OP_STATUS_ERROR;
+			return -1;
+		}
 
-	if (ret != COMP_OK) {
-		op->status = RTE_COMP_OP_STATUS_ERROR;
-		return ret;
-	}
+		if (ret != COMP_OK) {
+			op->status = RTE_COMP_OP_STATUS_ERROR;
+			return ret;
+		}
 
-	op->consumed = qp->stream->total_in;
-	op->produced = qp->stream->total_out;
+		op->consumed = qp->stream->total_in;
+		op->produced = qp->stream->total_out;
+	}
 
 	return ret;
 }
@@ -289,31 +420,43 @@ process_isal_inflate(struct rte_comp_op *op, struct isal_comp_qp *qp)
 		return -1;
 	}
 
-	/* Execute decompression operation */
-	ret = isal_inflate_stateless(qp->state);
-
-	if (ret == ISAL_OUT_OVERFLOW) {
-		ISAL_PMD_LOG(ERR, "Output buffer not big enough\n");
-		op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
-		return ret;
-	}
-
-	/* Check that input buffer has been fully consumed */
-	if (qp->state->avail_in != (uint32_t)0) {
-		ISAL_PMD_LOG(ERR, "Input buffer could not be read entirely\n");
-		op->status = RTE_COMP_OP_STATUS_ERROR;
+	if (op->m_src->pkt_len < op->src.length) {
+		ISAL_PMD_LOG(ERR, "Input mbuf(s) not big enough.\n");
+		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
 		return -1;
 	}
 
-	if (ret != ISAL_DECOMP_OK) {
-		op->status = RTE_COMP_OP_STATUS_ERROR;
-		return ret;
-	}
+	/* Chained mbuf input/output */
+	if (op->m_src->nb_segs > 1 || op->m_dst->nb_segs > 1) {
+		ret = chained_mbuf_decompression(op, qp);
+		if (ret < 0)
+			return ret;
+	} else {
+		/* Execute decompression operation */
+		ret = isal_inflate_stateless(qp->state);
+
+		if (ret == ISAL_OUT_OVERFLOW) {
+			ISAL_PMD_LOG(ERR, "Output buffer not big enough\n");
+			op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
+			return ret;
+		}
 
+		/* Check that input buffer has been fully consumed */
+		if (qp->state->avail_in != (uint32_t)0) {
+			ISAL_PMD_LOG(ERR, "Input buffer could not be read entirely\n");
+			op->status = RTE_COMP_OP_STATUS_ERROR;
+			return -1;
+		}
+
+		if (ret != ISAL_DECOMP_OK) {
+			op->status = RTE_COMP_OP_STATUS_ERROR;
+			return ret;
+		}
+	}
 	op->consumed = op->src.length - qp->state->avail_in;
 	op->produced = qp->state->total_out;
 
-return ret;
+	return ret;
 }
 
 /* Process compression/decompression operation */
@@ -353,6 +496,7 @@ isal_comp_pmd_enqueue_burst(void *queue_pair, struct rte_comp_op **ops,
 			continue;
 		}
 		retval = process_op(qp, ops[i], ops[i]->private_xform);
+
 		if (unlikely(retval < 0) ||
 				ops[i]->status != RTE_COMP_OP_STATUS_SUCCESS) {
 			qp->qp_stats.enqueue_err_count++;
diff --git a/drivers/compress/isal/isal_compress_pmd_ops.c b/drivers/compress/isal/isal_compress_pmd_ops.c
index 970a041..cf7bc6c 100644
--- a/drivers/compress/isal/isal_compress_pmd_ops.c
+++ b/drivers/compress/isal/isal_compress_pmd_ops.c
@@ -12,7 +12,8 @@
 static const struct rte_compressdev_capabilities isal_pmd_capabilities[] = {
 	{
 		.algo = RTE_COMP_ALGO_DEFLATE,
-		.comp_feature_flags =	RTE_COMP_FF_SHAREABLE_PRIV_XFORM,
+		.comp_feature_flags =	RTE_COMP_FF_SHAREABLE_PRIV_XFORM |
+					RTE_COMP_FF_MBUF_SCATTER_GATHER,
 		.window_size = {
 			.min = 15,
 			.max = 15,
-- 
2.7.4

             reply	other threads:[~2018-07-05 11:04 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-05 11:03 Lee Daly [this message]
2018-07-11 12:40 ` [PATCH v2] compress/isal: add chained mbuf support Lee, Daly
2018-07-20 10:38   ` De Lara Guarch, Pablo
2018-07-23 18:02   ` [PATCH v3] " Daly, Lee
2018-07-23 21:14     ` De Lara Guarch, Pablo
2018-07-24 11:19     ` [PATCH v4] " Daly, Lee
2018-07-24 13:27       ` De Lara Guarch, Pablo
2018-07-24 13:36         ` 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=1530788614-192928-1-git-send-email-lee.daly@intel.com \
    --to=lee.daly@intel.com \
    --cc=dev@dpdk.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.