get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 127721,
    "url": "http://patches.dpdk.org/api/patches/127721/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230530100158.1428-20-anoobj@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<20230530100158.1428-20-anoobj@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230530100158.1428-20-anoobj@marvell.com",
    "date": "2023-05-30T10:01:56",
    "name": "[v6,19/21] pdcp: add support for status report",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "18f294af4519e9c91b08a77cef7421e2351dbab8",
    "submitter": {
        "id": 1205,
        "url": "http://patches.dpdk.org/api/people/1205/?format=api",
        "name": "Anoob Joseph",
        "email": "anoobj@marvell.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230530100158.1428-20-anoobj@marvell.com/mbox/",
    "series": [
        {
            "id": 28249,
            "url": "http://patches.dpdk.org/api/series/28249/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=28249",
            "date": "2023-05-30T10:01:37",
            "name": "lib: add pdcp protocol",
            "version": 6,
            "mbox": "http://patches.dpdk.org/series/28249/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/127721/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/127721/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 0155B42BE2;\n\tTue, 30 May 2023 12:04:23 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 95C6E410EE;\n\tTue, 30 May 2023 12:03:28 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id 1E64542D38\n for <dev@dpdk.org>; Tue, 30 May 2023 12:03:27 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 34U8uFtt006350; Tue, 30 May 2023 03:03:26 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3quhcm7u0v-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Tue, 30 May 2023 03:03:26 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Tue, 30 May 2023 03:03:23 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend\n Transport; Tue, 30 May 2023 03:03:23 -0700",
            "from BG-LT92004.corp.innovium.com (unknown [10.193.69.246])\n by maili.marvell.com (Postfix) with ESMTP id 1F5373F7053;\n Tue, 30 May 2023 03:03:19 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0220;\n bh=9D/dGQau2jly2mTxP2Q5nyfnhv0sBksTjV+Ycii6jKo=;\n b=SKxXXsPK/xG3h6ZbpIN3E07qkP3w6kiVQUhEcCU3Q0oXQaPX9YDF4DYP72CQQuMOMANx\n 2iHWszLCv56cpvEGrdE6h+wITWNliggILtwLugQrWOL0OZUE+rrWIAjaVfRScgHIc61f\n 0DqzK1fLJ9PjxrFsFwLddE6Aud+h8moJPMSRqLTy9TTIuKwFM2BXYJmdZyNz5501+Rnj\n p7wdZ9JQDZSHIaa72THoa/jGHevgtYzMUYvjguCCync6RLumBJVrxsGgJQNp/kNpdLbu\n UqbNueWvpHq2QGeiEJOJ/Cmsqs6jeQJ/gSetHx/q5uHYDzO91602+SK7f0GPhGVvJV0H ww==",
        "From": "Anoob Joseph <anoobj@marvell.com>",
        "To": "Thomas Monjalon <thomas@monjalon.net>, Akhil Goyal <gakhil@marvell.com>,\n Jerin Jacob <jerinj@marvell.com>, Konstantin Ananyev\n <konstantin.v.ananyev@yandex.ru>",
        "CC": "Volodymyr Fialko <vfialko@marvell.com>,\n Hemant Agrawal <hemant.agrawal@nxp.com>,\n =?utf-8?q?Mattias_R=C3=B6nnblom?= <mattias.ronnblom@ericsson.com>,\n Kiran Kumar K <kirankumark@marvell.com>, <dev@dpdk.org>,\n Olivier Matz <olivier.matz@6wind.com>,\n Stephen Hemminger <stephen@networkplumber.org>",
        "Subject": "[PATCH v6 19/21] pdcp: add support for status report",
        "Date": "Tue, 30 May 2023 15:31:56 +0530",
        "Message-ID": "<20230530100158.1428-20-anoobj@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230530100158.1428-1-anoobj@marvell.com>",
        "References": "<20230527085910.972-1-anoobj@marvell.com>\n <20230530100158.1428-1-anoobj@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-GUID": "uSe31z53YjuwpIfkle0Xp_qa6ETN-Lcq",
        "X-Proofpoint-ORIG-GUID": "uSe31z53YjuwpIfkle0Xp_qa6ETN-Lcq",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.573,FMLib:17.11.176.26\n definitions=2023-05-30_06,2023-05-29_02,2023-05-22_02",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Volodymyr Fialko <vfialko@marvell.com>\n\nImplement status report generation for PDCP entity.\n\nSigned-off-by: Anoob Joseph <anoobj@marvell.com>\nSigned-off-by: Volodymyr Fialko <vfialko@marvell.com>\n---\n lib/pdcp/pdcp_cnt.c      | 158 ++++++++++++++++++++++++++++++++++++---\n lib/pdcp/pdcp_cnt.h      |  11 ++-\n lib/pdcp/pdcp_ctrl_pdu.c |  34 ++++++++-\n lib/pdcp/pdcp_ctrl_pdu.h |   3 +-\n lib/pdcp/pdcp_entity.h   |   2 +\n lib/pdcp/pdcp_process.c  |   9 ++-\n lib/pdcp/pdcp_process.h  |  13 ++++\n lib/pdcp/rte_pdcp.c      |  34 ++++++---\n 8 files changed, 236 insertions(+), 28 deletions(-)",
    "diff": "diff --git a/lib/pdcp/pdcp_cnt.c b/lib/pdcp/pdcp_cnt.c\nindex c9b952184b..af027b00d3 100644\n--- a/lib/pdcp/pdcp_cnt.c\n+++ b/lib/pdcp/pdcp_cnt.c\n@@ -2,28 +2,164 @@\n  * Copyright(C) 2023 Marvell.\n  */\n \n+#include <rte_bitmap.h>\n #include <rte_pdcp.h>\n \n #include \"pdcp_cnt.h\"\n+#include \"pdcp_ctrl_pdu.h\"\n #include \"pdcp_entity.h\"\n \n+#define SLAB_BYTE_SIZE (RTE_BITMAP_SLAB_BIT_SIZE / 8)\n+\n+uint32_t\n+pdcp_cnt_bitmap_get_memory_footprint(const struct rte_pdcp_entity_conf *conf)\n+{\n+\tuint32_t n_bits = pdcp_window_size_get(conf->pdcp_xfrm.sn_size);\n+\n+\treturn rte_bitmap_get_memory_footprint(n_bits);\n+}\n+\n int\n-pdcp_cnt_ring_create(struct rte_pdcp_entity *en, const struct rte_pdcp_entity_conf *conf)\n+pdcp_cnt_bitmap_create(struct entity_priv_dl_part *dl, void *bitmap_mem, uint32_t window_size)\n {\n-\tstruct entity_priv_dl_part *en_priv_dl;\n-\tuint32_t window_sz;\n+\tuint32_t mem_size = rte_bitmap_get_memory_footprint(window_size);\n \n-\tif (en == NULL || conf == NULL)\n+\tdl->bitmap.bmp = rte_bitmap_init(window_size, bitmap_mem, mem_size);\n+\tif (dl->bitmap.bmp == NULL)\n \t\treturn -EINVAL;\n \n-\tif (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK)\n-\t\treturn 0;\n+\tdl->bitmap.size = window_size;\n \n-\ten_priv_dl = entity_dl_part_get(en);\n-\twindow_sz = pdcp_window_size_get(conf->pdcp_xfrm.sn_size);\n+\treturn 0;\n+}\n \n-\tRTE_SET_USED(window_sz);\n-\tRTE_SET_USED(en_priv_dl);\n+void\n+pdcp_cnt_bitmap_set(struct pdcp_cnt_bitmap bitmap, uint32_t count)\n+{\n+\trte_bitmap_set(bitmap.bmp, count % bitmap.size);\n+}\n \n-\treturn 0;\n+bool\n+pdcp_cnt_bitmap_is_set(struct pdcp_cnt_bitmap bitmap, uint32_t count)\n+{\n+\treturn rte_bitmap_get(bitmap.bmp, count % bitmap.size);\n+}\n+\n+void\n+pdcp_cnt_bitmap_range_clear(struct pdcp_cnt_bitmap bitmap, uint32_t start, uint32_t stop)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = start; i < stop; i++)\n+\t\trte_bitmap_clear(bitmap.bmp, i % bitmap.size);\n+}\n+\n+uint16_t\n+pdcp_cnt_get_bitmap_size(uint32_t pending_bytes)\n+{\n+\t/*\n+\t * Round up bitmap size to slab size to operate only on slabs sizes, instead of individual\n+\t * bytes\n+\t */\n+\treturn RTE_ALIGN_MUL_CEIL(pending_bytes, SLAB_BYTE_SIZE);\n+}\n+\n+static __rte_always_inline uint64_t\n+leftover_get(uint64_t slab, uint32_t shift, uint64_t mask)\n+{\n+\treturn (slab & mask) << shift;\n+}\n+\n+void\n+pdcp_cnt_report_fill(struct pdcp_cnt_bitmap bitmap, struct entity_state state,\n+\t\t     uint8_t *data, uint16_t data_len)\n+{\n+\tuint64_t slab = 0, next_slab = 0, leftover;\n+\tuint32_t zeros, report_len, diff;\n+\tuint32_t slab_id, next_slab_id;\n+\tuint32_t pos = 0, next_pos = 0;\n+\n+\tconst uint32_t start_count = state.rx_deliv + 1;\n+\tconst uint32_t nb_slabs = bitmap.size / RTE_BITMAP_SLAB_BIT_SIZE;\n+\tconst uint32_t nb_data_slabs = data_len / SLAB_BYTE_SIZE;\n+\tconst uint32_t start_slab_id = start_count / RTE_BITMAP_SLAB_BIT_SIZE;\n+\tconst uint32_t stop_slab_id = (start_slab_id + nb_data_slabs) % nb_slabs;\n+\tconst uint32_t shift = start_count % RTE_BITMAP_SLAB_BIT_SIZE;\n+\tconst uint32_t leftover_shift = shift ? RTE_BITMAP_SLAB_BIT_SIZE - shift : 0;\n+\tconst uint8_t *data_end = RTE_PTR_ADD(data, data_len + SLAB_BYTE_SIZE);\n+\n+\t/* NOTE: Mask required to workaround case - when shift is not needed */\n+\tconst uint64_t leftover_mask = shift ? ~0 : 0;\n+\n+\t/* NOTE: implement scan init at to set custom position */\n+\t__rte_bitmap_scan_init(bitmap.bmp);\n+\twhile (true) {\n+\t\tassert(rte_bitmap_scan(bitmap.bmp, &pos, &slab) == 1);\n+\t\tslab_id = pos / RTE_BITMAP_SLAB_BIT_SIZE;\n+\t\tif (slab_id >= start_slab_id)\n+\t\t\tbreak;\n+\t}\n+\n+\treport_len = nb_data_slabs;\n+\n+\tif (slab_id > start_slab_id) {\n+\t\t/* Zero slabs at beginning */\n+\t\tzeros = (slab_id - start_slab_id - 1) * SLAB_BYTE_SIZE;\n+\t\tmemset(data, 0, zeros);\n+\t\tdata = RTE_PTR_ADD(data, zeros);\n+\t\tleftover = leftover_get(slab, leftover_shift, leftover_mask);\n+\t\tmemcpy(data, &leftover, SLAB_BYTE_SIZE);\n+\t\tdata = RTE_PTR_ADD(data, SLAB_BYTE_SIZE);\n+\t\treport_len -= (slab_id - start_slab_id);\n+\t}\n+\n+\twhile (report_len) {\n+\t\trte_bitmap_scan(bitmap.bmp, &next_pos, &next_slab);\n+\t\tnext_slab_id = next_pos / RTE_BITMAP_SLAB_BIT_SIZE;\n+\t\tdiff = (next_slab_id + nb_slabs - slab_id) % nb_slabs;\n+\n+\t\t/* If next_slab_id == slab_id - overlap */\n+\t\tdiff += !(next_slab_id ^ slab_id) * nb_slabs;\n+\n+\t\t/* Size check - next slab is outsize of size range */\n+\t\tif (diff > report_len) {\n+\t\t\tnext_slab = 0;\n+\t\t\tnext_slab_id = stop_slab_id;\n+\t\t\tdiff = report_len;\n+\t\t}\n+\n+\t\treport_len -= diff;\n+\n+\t\t/* Calculate gap between slabs, taking wrap around into account */\n+\t\tzeros = (next_slab_id + nb_slabs - slab_id - 1) % nb_slabs;\n+\t\tif (zeros) {\n+\t\t\t/* Non continues slabs, align them individually */\n+\t\t\tslab >>= shift;\n+\t\t\tmemcpy(data, &slab, SLAB_BYTE_SIZE);\n+\t\t\tdata = RTE_PTR_ADD(data, SLAB_BYTE_SIZE);\n+\n+\t\t\t/* Fill zeros between slabs */\n+\t\t\tzeros = (zeros - 1) * SLAB_BYTE_SIZE;\n+\t\t\tmemset(data, 0, zeros);\n+\t\t\tdata = RTE_PTR_ADD(data, zeros);\n+\n+\t\t\t/* Align beginning of next slab */\n+\t\t\tleftover = leftover_get(next_slab, leftover_shift, leftover_mask);\n+\t\t\tmemcpy(data, &leftover, SLAB_BYTE_SIZE);\n+\t\t\tdata = RTE_PTR_ADD(data, SLAB_BYTE_SIZE);\n+\t\t} else {\n+\t\t\t/* Continues slabs, combine them */\n+\t\t\tuint64_t new_slab = (slab >> shift) |\n+\t\t\t\t\tleftover_get(next_slab, leftover_shift, leftover_mask);\n+\t\t\tmemcpy(data, &new_slab, SLAB_BYTE_SIZE);\n+\t\t\tdata = RTE_PTR_ADD(data, SLAB_BYTE_SIZE);\n+\t\t}\n+\n+\t\tslab = next_slab;\n+\t\tpos = next_pos;\n+\t\tslab_id = next_slab_id;\n+\n+\t};\n+\n+\tassert(data < data_end);\n }\ndiff --git a/lib/pdcp/pdcp_cnt.h b/lib/pdcp/pdcp_cnt.h\nindex bbda478b55..5941b7a406 100644\n--- a/lib/pdcp/pdcp_cnt.h\n+++ b/lib/pdcp/pdcp_cnt.h\n@@ -9,6 +9,15 @@\n \n #include \"pdcp_entity.h\"\n \n-int pdcp_cnt_ring_create(struct rte_pdcp_entity *en, const struct rte_pdcp_entity_conf *conf);\n+uint32_t pdcp_cnt_bitmap_get_memory_footprint(const struct rte_pdcp_entity_conf *conf);\n+int pdcp_cnt_bitmap_create(struct entity_priv_dl_part *dl, void *bitmap_mem, uint32_t window_size);\n+\n+void pdcp_cnt_bitmap_set(struct pdcp_cnt_bitmap bitmap, uint32_t count);\n+bool pdcp_cnt_bitmap_is_set(struct pdcp_cnt_bitmap bitmap, uint32_t count);\n+void pdcp_cnt_bitmap_range_clear(struct pdcp_cnt_bitmap bitmap, uint32_t start, uint32_t stop);\n+\n+uint16_t pdcp_cnt_get_bitmap_size(uint32_t pending_bytes);\n+void pdcp_cnt_report_fill(struct pdcp_cnt_bitmap bitmap, struct entity_state state,\n+\t\t\t  uint8_t *data, uint16_t data_len);\n \n #endif /* PDCP_CNT_H */\ndiff --git a/lib/pdcp/pdcp_ctrl_pdu.c b/lib/pdcp/pdcp_ctrl_pdu.c\nindex feb05fd863..e0ac2d3720 100644\n--- a/lib/pdcp/pdcp_ctrl_pdu.c\n+++ b/lib/pdcp/pdcp_ctrl_pdu.c\n@@ -8,6 +8,14 @@\n \n #include \"pdcp_ctrl_pdu.h\"\n #include \"pdcp_entity.h\"\n+#include \"pdcp_cnt.h\"\n+\n+static inline uint16_t\n+round_up_bits(uint32_t bits)\n+{\n+\t/* round up to the next multiple of 8 */\n+\treturn RTE_ALIGN_MUL_CEIL(bits, 8) / 8;\n+}\n \n static __rte_always_inline void\n pdcp_hdr_fill(struct rte_pdcp_up_ctrl_pdu_hdr *pdu_hdr, uint32_t rx_deliv)\n@@ -19,11 +27,13 @@ pdcp_hdr_fill(struct rte_pdcp_up_ctrl_pdu_hdr *pdu_hdr, uint32_t rx_deliv)\n }\n \n int\n-pdcp_ctrl_pdu_status_gen(struct entity_priv *en_priv, struct rte_mbuf *m)\n+pdcp_ctrl_pdu_status_gen(struct entity_priv *en_priv, struct entity_priv_dl_part *dl,\n+\t\t\t struct rte_mbuf *m)\n {\n \tstruct rte_pdcp_up_ctrl_pdu_hdr *pdu_hdr;\n-\tuint32_t rx_deliv;\n-\tint pdu_sz;\n+\tuint32_t rx_deliv, actual_sz;\n+\tuint16_t pdu_sz, bitmap_sz;\n+\tuint8_t *data;\n \n \tif (!en_priv->flags.is_status_report_required)\n \t\treturn -EINVAL;\n@@ -42,5 +52,21 @@ pdcp_ctrl_pdu_status_gen(struct entity_priv *en_priv, struct rte_mbuf *m)\n \t\treturn 0;\n \t}\n \n-\treturn -ENOTSUP;\n+\tactual_sz = RTE_MIN(round_up_bits(en_priv->state.rx_next - rx_deliv - 1),\n+\t\t\tRTE_PDCP_CTRL_PDU_SIZE_MAX - pdu_sz);\n+\tbitmap_sz = pdcp_cnt_get_bitmap_size(actual_sz);\n+\n+\tdata = (uint8_t *)rte_pktmbuf_append(m, pdu_sz + bitmap_sz);\n+\tif (data == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tm->pkt_len = pdu_sz + actual_sz;\n+\tm->data_len = pdu_sz + actual_sz;\n+\n+\tpdcp_hdr_fill((struct rte_pdcp_up_ctrl_pdu_hdr *)data, rx_deliv);\n+\n+\tdata = RTE_PTR_ADD(data, pdu_sz);\n+\tpdcp_cnt_report_fill(dl->bitmap, en_priv->state, data, bitmap_sz);\n+\n+\treturn 0;\n }\ndiff --git a/lib/pdcp/pdcp_ctrl_pdu.h b/lib/pdcp/pdcp_ctrl_pdu.h\nindex a2424fbd10..2a87928b88 100644\n--- a/lib/pdcp/pdcp_ctrl_pdu.h\n+++ b/lib/pdcp/pdcp_ctrl_pdu.h\n@@ -10,6 +10,7 @@\n #include \"pdcp_entity.h\"\n \n int\n-pdcp_ctrl_pdu_status_gen(struct entity_priv *en_priv, struct rte_mbuf *m);\n+pdcp_ctrl_pdu_status_gen(struct entity_priv *en_priv, struct entity_priv_dl_part *dl,\n+\t\t\t struct rte_mbuf *m);\n \n #endif /* PDCP_CTRL_PDU_H */\ndiff --git a/lib/pdcp/pdcp_entity.h b/lib/pdcp/pdcp_entity.h\nindex efc74ba9b9..a9b1428c7a 100644\n--- a/lib/pdcp/pdcp_entity.h\n+++ b/lib/pdcp/pdcp_entity.h\n@@ -182,6 +182,8 @@ struct entity_priv_dl_part {\n \tstruct pdcp_t_reordering t_reorder;\n \t/** Reorder packet buffer */\n \tstruct pdcp_reorder reorder;\n+\t/** Bitmap memory region */\n+\tuint8_t bitmap_mem[0];\n };\n \n struct entity_priv_ul_part {\ndiff --git a/lib/pdcp/pdcp_process.c b/lib/pdcp/pdcp_process.c\nindex daf2c27363..774f5646d8 100644\n--- a/lib/pdcp/pdcp_process.c\n+++ b/lib/pdcp/pdcp_process.c\n@@ -10,6 +10,7 @@\n #include <rte_pdcp.h>\n #include <rte_pdcp_hdr.h>\n \n+#include \"pdcp_cnt.h\"\n #include \"pdcp_crypto.h\"\n #include \"pdcp_entity.h\"\n #include \"pdcp_process.h\"\n@@ -857,11 +858,15 @@ pdcp_post_process_update_entity_state(const struct rte_pdcp_entity *entity,\n \tif (count >= en_priv->state.rx_next)\n \t\ten_priv->state.rx_next = count + 1;\n \n+\tif (unlikely(pdcp_cnt_bitmap_is_set(dl->bitmap, count)))\n+\t\treturn -EEXIST;\n+\n+\tpdcp_cnt_bitmap_set(dl->bitmap, count);\n \tpdcp_packet_strip(mb, hdr_trim_sz, trim_mac);\n \n \tif (en_priv->flags.is_out_of_order_delivery) {\n \t\tout_mb[0] = mb;\n-\t\ten_priv->state.rx_deliv = count + 1;\n+\t\tpdcp_rx_deliv_set(entity, count + 1);\n \n \t\treturn 1;\n \t}\n@@ -888,7 +893,7 @@ pdcp_post_process_update_entity_state(const struct rte_pdcp_entity *entity,\n \t\t}\n \n \t\t/* Processed should never exceed the window size */\n-\t\ten_priv->state.rx_deliv = count + processed;\n+\t\tpdcp_rx_deliv_set(entity, count + processed);\n \n \t} else {\n \t\tif (!reorder->is_active)\ndiff --git a/lib/pdcp/pdcp_process.h b/lib/pdcp/pdcp_process.h\nindex a52f769b82..fa3d93b405 100644\n--- a/lib/pdcp/pdcp_process.h\n+++ b/lib/pdcp/pdcp_process.h\n@@ -8,6 +8,9 @@\n #include <rte_mbuf_dyn.h>\n #include <rte_pdcp.h>\n \n+#include <pdcp_entity.h>\n+#include <pdcp_cnt.h>\n+\n typedef uint32_t rte_pdcp_dynfield_t;\n \n extern int rte_pdcp_dynfield_offset;\n@@ -21,4 +24,14 @@ pdcp_dynfield(struct rte_mbuf *mbuf)\n int\n pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_entity_conf *conf);\n \n+static inline void\n+pdcp_rx_deliv_set(const struct rte_pdcp_entity *entity, uint32_t rx_deliv)\n+{\n+\tstruct entity_priv_dl_part *dl = entity_dl_part_get(entity);\n+\tstruct entity_priv *en_priv = entity_priv_get(entity);\n+\n+\tpdcp_cnt_bitmap_range_clear(dl->bitmap, en_priv->state.rx_deliv, rx_deliv);\n+\ten_priv->state.rx_deliv = rx_deliv;\n+}\n+\n #endif /* PDCP_PROCESS_H */\ndiff --git a/lib/pdcp/rte_pdcp.c b/lib/pdcp/rte_pdcp.c\nindex 819c66bd08..9865c620b7 100644\n--- a/lib/pdcp/rte_pdcp.c\n+++ b/lib/pdcp/rte_pdcp.c\n@@ -14,6 +14,8 @@\n \n #define RTE_PDCP_DYNFIELD_NAME \"rte_pdcp_dynfield\"\n \n+static int bitmap_mem_offset;\n+\n int rte_pdcp_dynfield_offset = -1;\n \n static int\n@@ -39,9 +41,12 @@ pdcp_entity_size_get(const struct rte_pdcp_entity_conf *conf)\n \n \tsize = sizeof(struct rte_pdcp_entity) + sizeof(struct entity_priv);\n \n-\tif (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)\n+\tif (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK) {\n \t\tsize += sizeof(struct entity_priv_dl_part);\n-\telse if (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK)\n+\t\tsize = RTE_CACHE_LINE_ROUNDUP(size);\n+\t\tbitmap_mem_offset = size;\n+\t\tsize += pdcp_cnt_bitmap_get_memory_footprint(conf);\n+\t} else if (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK)\n \t\tsize += sizeof(struct entity_priv_ul_part);\n \telse\n \t\treturn -EINVAL;\n@@ -54,11 +59,24 @@ pdcp_dl_establish(struct rte_pdcp_entity *entity, const struct rte_pdcp_entity_c\n {\n \tconst uint32_t window_size = pdcp_window_size_get(conf->pdcp_xfrm.sn_size);\n \tstruct entity_priv_dl_part *dl = entity_dl_part_get(entity);\n+\tvoid *bitmap_mem;\n+\tint ret;\n \n \tentity->max_pkt_cache = RTE_MAX(entity->max_pkt_cache, window_size);\n \tdl->t_reorder.handle = conf->t_reordering;\n \n-\treturn pdcp_reorder_create(&dl->reorder, window_size);\n+\tret = pdcp_reorder_create(&dl->reorder, window_size);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tbitmap_mem = RTE_PTR_ADD(entity, bitmap_mem_offset);\n+\tret = pdcp_cnt_bitmap_create(dl, bitmap_mem, window_size);\n+\tif (ret) {\n+\t\tpdcp_reorder_destroy(&dl->reorder);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n }\n \n struct rte_pdcp_entity *\n@@ -136,10 +154,6 @@ rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf *conf)\n \t\t\tgoto crypto_sess_destroy;\n \t}\n \n-\tret = pdcp_cnt_ring_create(entity, conf);\n-\tif (ret)\n-\t\tgoto crypto_sess_destroy;\n-\n \treturn entity;\n \n crypto_sess_destroy:\n@@ -218,6 +232,7 @@ struct rte_mbuf *\n rte_pdcp_control_pdu_create(struct rte_pdcp_entity *pdcp_entity,\n \t\t\t    enum rte_pdcp_ctrl_pdu_type type)\n {\n+\tstruct entity_priv_dl_part *dl;\n \tstruct entity_priv *en_priv;\n \tstruct rte_mbuf *m;\n \tint ret;\n@@ -228,6 +243,7 @@ rte_pdcp_control_pdu_create(struct rte_pdcp_entity *pdcp_entity,\n \t}\n \n \ten_priv = entity_priv_get(pdcp_entity);\n+\tdl = entity_dl_part_get(pdcp_entity);\n \n \tm = rte_pktmbuf_alloc(en_priv->ctrl_pdu_pool);\n \tif (m == NULL) {\n@@ -237,7 +253,7 @@ rte_pdcp_control_pdu_create(struct rte_pdcp_entity *pdcp_entity,\n \n \tswitch (type) {\n \tcase RTE_PDCP_CTRL_PDU_TYPE_STATUS_REPORT:\n-\t\tret = pdcp_ctrl_pdu_status_gen(en_priv, m);\n+\t\tret = pdcp_ctrl_pdu_status_gen(en_priv, dl, m);\n \t\tbreak;\n \tdefault:\n \t\tret = -ENOTSUP;\n@@ -283,7 +299,7 @@ rte_pdcp_t_reordering_expiry_handle(const struct rte_pdcp_entity *entity, struct\n \t * - update RX_DELIV to the COUNT value of the first PDCP SDU which has not been delivered\n \t *   to upper layers, with COUNT value >= RX_REORD;\n \t */\n-\ten_priv->state.rx_deliv = en_priv->state.rx_reord + nb_seq;\n+\tpdcp_rx_deliv_set(entity, en_priv->state.rx_reord + nb_seq);\n \n \t/*\n \t * - if RX_DELIV < RX_NEXT:\n",
    "prefixes": [
        "v6",
        "19/21"
    ]
}