get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/43283/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 43283,
    "url": "https://patches.dpdk.org/api/patches/43283/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1532368945-23909-1-git-send-email-lee.daly@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1532368945-23909-1-git-send-email-lee.daly@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1532368945-23909-1-git-send-email-lee.daly@intel.com",
    "date": "2018-07-23T18:02:25",
    "name": "[v3] compress/isal: add chained mbuf support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8e0f104a23a86ca440e8ce6d9eb504e744b7c8eb",
    "submitter": {
        "id": 825,
        "url": "https://patches.dpdk.org/api/people/825/?format=api",
        "name": "Daly, Lee",
        "email": "lee.daly@intel.com"
    },
    "delegate": {
        "id": 22,
        "url": "https://patches.dpdk.org/api/users/22/?format=api",
        "username": "pdelarag",
        "first_name": "Pablo",
        "last_name": "de Lara Guarch",
        "email": "pablo.de.lara.guarch@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1532368945-23909-1-git-send-email-lee.daly@intel.com/mbox/",
    "series": [
        {
            "id": 720,
            "url": "https://patches.dpdk.org/api/series/720/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=720",
            "date": "2018-07-23T18:02:25",
            "name": "[v3] compress/isal: add chained mbuf support",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/720/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/43283/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/43283/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id CAFD2F94;\n\tMon, 23 Jul 2018 20:03:36 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n\tby dpdk.org (Postfix) with ESMTP id 0A1D1235\n\tfor <dev@dpdk.org>; Mon, 23 Jul 2018 20:03:34 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t23 Jul 2018 11:03:34 -0700",
            "from silpixa00399501.ir.intel.com ([10.237.223.69])\n\tby fmsmga006.fm.intel.com with ESMTP; 23 Jul 2018 11:03:32 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.51,394,1526367600\"; d=\"scan'208\";a=\"248179407\"",
        "From": "\"Daly, Lee\" <lee.daly@intel.com>",
        "To": "pablo.de.lara.guarch@intel.com",
        "Cc": "dev@dpdk.org,\n\t\"Daly, Lee\" <lee.daly@intel.com>",
        "Date": "Mon, 23 Jul 2018 19:02:25 +0100",
        "Message-Id": "<1532368945-23909-1-git-send-email-lee.daly@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1531312811-177746-1-git-send-email-lee.daly@intel.com>",
        "References": "<1531312811-177746-1-git-send-email-lee.daly@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3] compress/isal: add chained mbuf support",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch adds chained mbuf support for input or output buffers\nduring compression/decompression operations.\n\nSigned-off-by: Lee Daly <lee.daly@intel.com>\n---\n doc/guides/compressdevs/features/isal.ini     |  17 +-\n doc/guides/compressdevs/isal.rst              |   2 -\n drivers/compress/isal/isal_compress_pmd.c     | 397 ++++++++++++++++++++------\n drivers/compress/isal/isal_compress_pmd_ops.c |   5 +-\n 4 files changed, 323 insertions(+), 98 deletions(-)",
    "diff": "diff --git a/doc/guides/compressdevs/features/isal.ini b/doc/guides/compressdevs/features/isal.ini\nindex 7183d10..919cf70 100644\n--- a/doc/guides/compressdevs/features/isal.ini\n+++ b/doc/guides/compressdevs/features/isal.ini\n@@ -4,10 +4,13 @@\n ; Supported features of 'ISA-L' compression driver.\n ;\n [Features]\n-CPU SSE        = Y\n-CPU AVX        = Y\n-CPU AVX2       = Y\n-CPU AVX512     = Y\n-Deflate        = Y\n-Fixed          = Y\n-Dynamic        = Y\n+CPU SSE            = Y\n+CPU AVX            = Y\n+CPU AVX2           = Y\n+CPU AVX512         = Y\n+OOP SGL In SGL Out = Y\n+OOP SGL In LB  Out = Y\n+OOP LB  In SGL Out = Y\n+Deflate            = Y\n+Fixed              = Y\n+Dynamic            = Y\ndiff --git a/doc/guides/compressdevs/isal.rst b/doc/guides/compressdevs/isal.rst\nindex 276ff06..3bc3022 100644\n--- a/doc/guides/compressdevs/isal.rst\n+++ b/doc/guides/compressdevs/isal.rst\n@@ -78,8 +78,6 @@ As a result the level mappings from the API to the PMD are shown below.\n Limitations\n -----------\n \n-* 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.\n-\n * Compressdev level 0, no compression, is not supported.\n \n * Checksums will not be supported until future release.\ndiff --git a/drivers/compress/isal/isal_compress_pmd.c b/drivers/compress/isal/isal_compress_pmd.c\nindex 5966cc3..a776019 100644\n--- a/drivers/compress/isal/isal_compress_pmd.c\n+++ b/drivers/compress/isal/isal_compress_pmd.c\n@@ -188,6 +188,206 @@ isal_comp_set_priv_xform_parameters(struct isal_priv_xform *priv_xform,\n \treturn 0;\n }\n \n+/* Compression using chained mbufs for input/output data */\n+static int\n+chained_mbuf_compression(struct rte_comp_op *op, struct isal_comp_qp *qp)\n+{\n+\tint ret;\n+\tuint32_t remaining_offset;\n+\tuint32_t remaining_data = op->src.length;\n+\tstruct rte_mbuf *src = op->m_src;\n+\tstruct rte_mbuf *dst = op->m_dst;\n+\n+\t/* check for offset passing multiple segments\n+\t * and point compression stream to input/output buffer\n+\t */\n+\tif (op->src.offset > src->data_len) {\n+\t\tremaining_offset = op->src.offset;\n+\t\twhile (remaining_offset > src->data_len) {\n+\t\t\tremaining_offset -= src->data_len;\n+\t\t\tsrc = src->next;\n+\t\t}\n+\n+\n+\t\tqp->stream->avail_in = src->data_len - remaining_offset;\n+\t\tqp->stream->next_in = rte_pktmbuf_mtod_offset(src, uint8_t *,\n+\t\t\t\t(op->src.offset % src->data_len));\n+\t} else {\n+\t\tqp->stream->avail_in = src->data_len - op->src.offset;\n+\t\tqp->stream->next_in = rte_pktmbuf_mtod_offset(src, uint8_t *,\n+\t\t\t\top->src.offset);\n+\t}\n+\n+\tif (op->dst.offset > dst->data_len) {\n+\t\tremaining_offset = op->dst.offset;\n+\t\twhile (remaining_offset > dst->data_len) {\n+\t\t\tremaining_offset -= dst->data_len;\n+\t\t\tdst = dst->next;\n+\t\t}\n+\n+\t\tqp->stream->avail_out = dst->data_len - remaining_offset;\n+\t\tqp->stream->next_out = rte_pktmbuf_mtod_offset(dst, uint8_t *,\n+\t\t\t\t(op->dst.offset % dst->data_len));\n+\t} else {\n+\t\tqp->stream->avail_out = dst->data_len - op->dst.offset;\n+\t\tqp->stream->next_out = rte_pktmbuf_mtod_offset(dst, uint8_t *,\n+\t\t\t\top->dst.offset);\n+\t}\n+\n+\tif (unlikely(!qp->stream->next_in || !qp->stream->next_out)) {\n+\t\tISAL_PMD_LOG(ERR, \"Invalid source or destination buffer\\n\");\n+\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n+\t\treturn -1;\n+\t}\n+\n+\twhile (qp->stream->internal_state.state != ZSTATE_END) {\n+\t\t/* Last segment of data */\n+\t\tif (remaining_data <= src->data_len)\n+\t\t\tqp->stream->end_of_stream = 1;\n+\n+\t\t/* Execute compression operation */\n+\t\tret = isal_deflate(qp->stream);\n+\n+\t\tremaining_data = op->src.length - qp->stream->total_in;\n+\n+\t\tif (ret != COMP_OK) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Compression operation failed\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tif (qp->stream->avail_in == 0 &&\n+\t\t\t\tqp->stream->total_in != op->src.length) {\n+\t\t\tif (src->next != NULL) {\n+\t\t\t\tsrc = src->next;\n+\t\t\t\tqp->stream->next_in =\n+\t\t\t\t\t\trte_pktmbuf_mtod(src, uint8_t *);\n+\t\t\t\tqp->stream->avail_in =\n+\t\t\t\t\tRTE_MIN(remaining_data, src->data_len);\n+\t\t\t} else {\n+\t\t\t\tISAL_PMD_LOG(ERR,\n+\t\t\t\t\"Not enough input buffer segments\\n\");\n+\t\t\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (qp->stream->avail_out == 0 &&\n+\t\t\t\tqp->stream->internal_state.state != ZSTATE_END) {\n+\t\t\tif (dst->next != NULL) {\n+\t\t\t\tdst = dst->next;\n+\t\t\t\tqp->stream->next_out =\n+\t\t\t\t\t\trte_pktmbuf_mtod(dst, uint8_t *);\n+\t\t\t\tqp->stream->avail_out = dst->data_len;\n+\t\t\t} else {\n+\t\t\t\tISAL_PMD_LOG(ERR,\n+\t\t\t\t\"Not enough output buffer segments\\n\");\n+\t\t\t\top->status =\n+\t\t\t\tRTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t}\n+\t}\n+\top->consumed = qp->stream->total_in;\n+\top->produced = qp->stream->total_out;\n+\n+\treturn 0;\n+}\n+\n+/* Decompression using chained mbufs for input/output data */\n+static int\n+chained_mbuf_decompression(struct rte_comp_op *op, struct isal_comp_qp *qp)\n+{\n+\tint ret;\n+\tuint32_t consumed_data, remaining_offset;\n+\tuint32_t remaining_data = op->src.length;\n+\tstruct rte_mbuf *src = op->m_src;\n+\tstruct rte_mbuf *dst = op->m_dst;\n+\n+\t/* check for offset passing multiple segments\n+\t * and point decompression state to input/output buffer\n+\t */\n+\tif (op->src.offset > src->data_len) {\n+\t\tremaining_offset = op->src.offset;\n+\t\twhile (remaining_offset > src->data_len) {\n+\t\t\tremaining_offset -= src->data_len;\n+\t\t\tsrc = src->next;\n+\t\t}\n+\n+\t\tqp->state->avail_in = src->data_len - remaining_offset;\n+\t\tqp->state->next_in = rte_pktmbuf_mtod_offset(src,\n+\t\t\t\tuint8_t *, (op->src.offset % src->data_len));\n+\t} else {\n+\t\tqp->state->avail_in = src->data_len - op->src.offset;\n+\t\tqp->state->next_in = rte_pktmbuf_mtod_offset(src, uint8_t *,\n+\t\t\t\top->src.offset);\n+\t}\n+\tif (op->dst.offset > dst->data_len) {\n+\t\tremaining_offset = op->dst.offset;\n+\t\twhile (remaining_offset > dst->data_len) {\n+\t\t\tremaining_offset -= dst->data_len;\n+\t\t\tdst = dst->next;\n+\t\t}\n+\n+\t\tqp->state->avail_out = dst->data_len - remaining_offset;\n+\t\tqp->state->next_out = rte_pktmbuf_mtod_offset(dst, uint8_t *,\n+\t\t\t\t(op->dst.offset % dst->data_len));\n+\t} else {\n+\t\tqp->state->avail_out = dst->data_len - op->dst.offset;\n+\t\tqp->state->next_out = rte_pktmbuf_mtod_offset(dst, uint8_t *,\n+\t\t\t\top->dst.offset);\n+\t}\n+\twhile (qp->state->block_state != ISAL_BLOCK_FINISH) {\n+\n+\t\tret = isal_inflate(qp->state);\n+\n+\t\tif (remaining_data == op->src.length) {\n+\t\t\tconsumed_data = src->data_len - qp->state->avail_in -\n+\t\t\t\t\t(op->src.offset % src->data_len);\n+\t\t} else\n+\t\t\tconsumed_data = src->data_len - qp->state->avail_in;\n+\n+\t\top->consumed += consumed_data;\n+\t\tremaining_data -= consumed_data;\n+\n+\t\tif (ret != ISAL_DECOMP_OK) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Decompression operation failed\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tif (qp->state->avail_in == 0\n+\t\t\t\t&& op->consumed != op->src.length) {\n+\t\t\tif (src->next != NULL) {\n+\t\t\t\tsrc = src->next;\n+\t\t\t\tqp->state->next_in =\n+\t\t\t\t\t\trte_pktmbuf_mtod(src, uint8_t *);\n+\t\t\t\tqp->state->avail_in =\n+\t\t\t\t\tRTE_MIN(remaining_data, src->data_len);\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (qp->state->avail_out == 0 &&\n+\t\t\t\tqp->state->block_state != ISAL_BLOCK_FINISH) {\n+\t\t\tif (dst->next != NULL) {\n+\t\t\t\tdst = dst->next;\n+\t\t\t\tqp->state->next_out =\n+\t\t\t\t\t\trte_pktmbuf_mtod(dst, uint8_t *);\n+\t\t\t\tqp->state->avail_out = dst->data_len;\n+\t\t\t} else {\n+\t\t\t\tISAL_PMD_LOG(ERR,\n+\t\t\t\t\"Not enough output buffer segments\\n\");\n+\t\t\t\top->status =\n+\t\t\t\tRTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t}\n+\t}\n+\top->produced = qp->state->total_out;\n+\n+\treturn 0;\n+}\n+\n /* Stateless Compression Function */\n static int\n process_isal_deflate(struct rte_comp_op *op, struct isal_comp_qp *qp,\n@@ -207,7 +407,7 @@ process_isal_deflate(struct rte_comp_op *op, struct isal_comp_qp *qp,\n \t/* Stateless operation, input will be consumed in one go */\n \tqp->stream->flush = NO_FLUSH;\n \n-\t/* set op level & intermediate level buffer */\n+\t/* set compression level & intermediate level buffer size */\n \tqp->stream->level = priv_xform->compress.level;\n \tqp->stream->level_buf_size = priv_xform->level_buffer_size;\n \n@@ -225,59 +425,70 @@ process_isal_deflate(struct rte_comp_op *op, struct isal_comp_qp *qp,\n \t\tisal_deflate_set_hufftables(qp->stream, NULL,\n \t\t\t\tIGZIP_HUFFTABLE_DEFAULT);\n \n-\tqp->stream->end_of_stream = 1; /* All input consumed in one go */\n-\tif ((op->src.length + op->src.offset) > op->m_src->data_len) {\n-\t\tISAL_PMD_LOG(ERR, \"Input mbuf not big enough for the length and\"\n-\t\t\t\t\" offset provided.\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n-\t\treturn -1;\n-\t}\n-\t/* Point compression stream to input buffer */\n-\tqp->stream->avail_in = op->src.length;\n-\tqp->stream->next_in = rte_pktmbuf_mtod_offset(op->m_src, uint8_t *,\n-\t\t\top->src.offset);\n-\n-\tif (op->dst.offset > op->m_dst->data_len) {\n-\t\tISAL_PMD_LOG(ERR, \"Output mbuf not big enough for the length\"\n-\t\t\t\t\" and offset provided.\\n\");\n+\tif (op->m_src->pkt_len < (op->src.length + op->src.offset)) {\n+\t\tISAL_PMD_LOG(ERR, \"Input mbuf(s) not big enough.\\n\");\n \t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n \t\treturn -1;\n \t}\n-\t/*  Point compression stream to output buffer */\n-\tqp->stream->avail_out = op->m_dst->data_len - op->dst.offset;\n-\tqp->stream->next_out  = rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *,\n-\t\top->dst.offset);\n \n-\tif (unlikely(!qp->stream->next_in || !qp->stream->next_out)) {\n-\t\tISAL_PMD_LOG(ERR, \"Invalid source or destination buffers\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n-\t\treturn -1;\n-\t}\n+\t/* Chained mbufs */\n+\tif (op->m_src->nb_segs > 1 || op->m_dst->nb_segs > 1) {\n+\t\tret = chained_mbuf_compression(op, qp);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t} else {\n+\t/* Linear buffer */\n+\t\tqp->stream->end_of_stream = 1; /* All input consumed in one */\n+\t\t/* Point compression stream to input buffer */\n+\t\tqp->stream->avail_in = op->src.length;\n+\t\tqp->stream->next_in = rte_pktmbuf_mtod_offset(op->m_src,\n+\t\t\t\tuint8_t *, op->src.offset);\n+\n+\t\tif (op->dst.offset > op->m_dst->data_len) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Output mbuf not big enough for \"\n+\t\t\t\t\t\"length and offset provided.\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n+\t\t\treturn -1;\n+\t\t}\n+\t\t/*  Point compression stream to output buffer */\n+\t\tqp->stream->avail_out = op->m_dst->data_len - op->dst.offset;\n+\t\tqp->stream->next_out  = rte_pktmbuf_mtod_offset(op->m_dst,\n+\t\t\t\tuint8_t *, op->dst.offset);\n+\n+\t\tif (unlikely(!qp->stream->next_in || !qp->stream->next_out)) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Invalid source or destination\"\n+\t\t\t\t\t\" buffers\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n+\t\t\treturn -1;\n+\t\t}\n \n-\t/* Execute compression operation */\n-\tret =  isal_deflate_stateless(qp->stream);\n+\t\t/* Execute compression operation */\n+\t\tret =  isal_deflate_stateless(qp->stream);\n \n-\t/* Check that output buffer did not run out of space */\n-\tif (ret == STATELESS_OVERFLOW) {\n-\t\tISAL_PMD_LOG(ERR, \"Output buffer not big enough\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;\n-\t\treturn ret;\n-\t}\n+\t\t/* Check that output buffer did not run out of space */\n+\t\tif (ret == STATELESS_OVERFLOW) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Output buffer not big enough\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;\n+\t\t\treturn ret;\n+\t\t}\n \n-\t/* Check that input buffer has been fully consumed */\n-\tif (qp->stream->avail_in != (uint32_t)0) {\n-\t\tISAL_PMD_LOG(ERR, \"Input buffer could not be read entirely\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n-\t\treturn -1;\n-\t}\n+\t\t/* Check that input buffer has been fully consumed */\n+\t\tif (qp->stream->avail_in != (uint32_t)0) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Input buffer could not be read\"\n+\t\t\t\t\t\" entirely\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n+\t\t\treturn -1;\n+\t\t}\n \n-\tif (ret != COMP_OK) {\n-\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n-\t\treturn ret;\n-\t}\n+\t\tif (ret != COMP_OK) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Compression operation failed\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n+\t\t\treturn ret;\n+\t\t}\n \n-\top->consumed = qp->stream->total_in;\n-\top->produced = qp->stream->total_out;\n+\t\top->consumed = qp->stream->total_in;\n+\t\top->produced = qp->stream->total_out;\n+\t}\n \n \treturn ret;\n }\n@@ -293,59 +504,69 @@ process_isal_inflate(struct rte_comp_op *op, struct isal_comp_qp *qp)\n \t/* Initialize decompression state */\n \tisal_inflate_init(qp->state);\n \n-\tif ((op->src.length + op->src.offset) > op->m_src->data_len) {\n-\t\tISAL_PMD_LOG(ERR, \"Input mbuf not big enough for the length and\"\n-\t\t\t\t\" offset provided.\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n-\t\treturn -1;\n-\t}\n-\t/* Point decompression state to input buffer */\n-\tqp->state->avail_in = op->src.length;\n-\tqp->state->next_in = rte_pktmbuf_mtod_offset(op->m_src, uint8_t *,\n-\t\t\top->src.offset);\n-\n-\tif (op->dst.offset > op->m_dst->data_len) {\n-\t\tISAL_PMD_LOG(ERR, \"Output mbuf not big enough for the length \"\n-\t\t\t\t\"and offset provided.\\n\");\n+\tif (op->m_src->pkt_len < (op->src.length + op->src.offset)) {\n+\t\tISAL_PMD_LOG(ERR, \"Input mbuf(s) not big enough.\\n\");\n \t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n \t\treturn -1;\n \t}\n-\t/* Point decompression state to output buffer */\n-\tqp->state->avail_out = op->m_dst->data_len - op->dst.offset;\n-\tqp->state->next_out  = rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *,\n-\t\t\top->dst.offset);\n \n-\tif (unlikely(!qp->state->next_in || !qp->state->next_out)) {\n-\t\tISAL_PMD_LOG(ERR, \"Invalid source or destination buffers\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n-\t\treturn -1;\n-\t}\n+\t/* Chained mbufs */\n+\tif (op->m_src->nb_segs > 1 || op->m_dst->nb_segs > 1) {\n+\t\tret = chained_mbuf_decompression(op, qp);\n+\t\tif (ret !=  0)\n+\t\t\treturn ret;\n+\t} else {\n+\t\t/* Linear buffer */\n+\t\t/* Point decompression state to input buffer */\n+\t\tqp->state->avail_in = op->src.length;\n+\t\tqp->state->next_in = rte_pktmbuf_mtod_offset(op->m_src,\n+\t\t\t\tuint8_t *, op->src.offset);\n+\n+\t\tif (op->dst.offset > op->m_dst->data_len) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Output mbuf not big enough for \"\n+\t\t\t\t\t\"length and offset provided.\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n+\t\t\treturn -1;\n+\t\t}\n+\t\t/* Point decompression state to output buffer */\n+\t\tqp->state->avail_out = op->m_dst->data_len - op->dst.offset;\n+\t\tqp->state->next_out  = rte_pktmbuf_mtod_offset(op->m_dst,\n+\t\t\t\tuint8_t *, op->dst.offset);\n+\n+\t\tif (unlikely(!qp->state->next_in || !qp->state->next_out)) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Invalid source or destination\"\n+\t\t\t\t\t\" buffers\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_INVALID_ARGS;\n+\t\t\treturn -1;\n+\t\t}\n \n-\t/* Execute decompression operation */\n-\tret = isal_inflate_stateless(qp->state);\n+\t\t/* Execute decompression operation */\n+\t\tret = isal_inflate_stateless(qp->state);\n \n-\tif (ret == ISAL_OUT_OVERFLOW) {\n-\t\tISAL_PMD_LOG(ERR, \"Output buffer not big enough\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;\n-\t\treturn ret;\n-\t}\n+\t\tif (ret == ISAL_OUT_OVERFLOW) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Output buffer not big enough\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;\n+\t\t\treturn ret;\n+\t\t}\n \n-\t/* Check that input buffer has been fully consumed */\n-\tif (qp->state->avail_in != (uint32_t)0) {\n-\t\tISAL_PMD_LOG(ERR, \"Input buffer could not be read entirely\\n\");\n-\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n-\t\treturn -1;\n-\t}\n+\t\t/* Check that input buffer has been fully consumed */\n+\t\tif (qp->state->avail_in != (uint32_t)0) {\n+\t\t\tISAL_PMD_LOG(ERR, \"Input buffer could not be read\"\n+\t\t\t\t\t\" entirely\\n\");\n+\t\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n+\t\t\treturn -1;\n+\t\t}\n \n-\tif (ret != ISAL_DECOMP_OK) {\n-\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n-\t\treturn ret;\n-\t}\n+\t\tif (ret != ISAL_DECOMP_OK) {\n+\t\t\top->status = RTE_COMP_OP_STATUS_ERROR;\n+\t\t\treturn ret;\n+\t\t}\n \n-\top->consumed = op->src.length - qp->state->avail_in;\n-\top->produced = qp->state->total_out;\n+\t\top->consumed = op->src.length - qp->state->avail_in;\n+\t\top->produced = qp->state->total_out;\n+\t}\n \n-return ret;\n+\treturn ret;\n }\n \n /* Process compression/decompression operation */\ndiff --git a/drivers/compress/isal/isal_compress_pmd_ops.c b/drivers/compress/isal/isal_compress_pmd_ops.c\nindex c61acd4..41cade8 100644\n--- a/drivers/compress/isal/isal_compress_pmd_ops.c\n+++ b/drivers/compress/isal/isal_compress_pmd_ops.c\n@@ -12,7 +12,10 @@\n static const struct rte_compressdev_capabilities isal_pmd_capabilities[] = {\n \t{\n \t\t.algo = RTE_COMP_ALGO_DEFLATE,\n-\t\t.comp_feature_flags =\tRTE_COMP_FF_SHAREABLE_PRIV_XFORM |\n+\t\t.comp_feature_flags =\tRTE_COMP_FF_OOP_SGL_IN_SGL_OUT |\n+\t\t\t\t\tRTE_COMP_FF_OOP_SGL_IN_LB_OUT |\n+\t\t\t\t\tRTE_COMP_FF_OOP_LB_IN_SGL_OUT |\n+\t\t\t\t\tRTE_COMP_FF_SHAREABLE_PRIV_XFORM |\n \t\t\t\t\tRTE_COMP_FF_HUFFMAN_FIXED |\n \t\t\t\t\tRTE_COMP_FF_HUFFMAN_DYNAMIC,\n \t\t.window_size = {\n",
    "prefixes": [
        "v3"
    ]
}