get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 102108,
    "url": "http://patchwork.dpdk.org/api/patches/102108/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20211018224353.3362537-5-dkozlyuk@nvidia.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20211018224353.3362537-5-dkozlyuk@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211018224353.3362537-5-dkozlyuk@nvidia.com",
    "date": "2021-10-18T22:43:53",
    "name": "[v9,4/4] net/mlx5: support mempool registration",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "8d7822daa7afc0e75f5b03da6e16303c8f4b4845",
    "submitter": {
        "id": 2367,
        "url": "http://patchwork.dpdk.org/api/people/2367/?format=api",
        "name": "Dmitry Kozlyuk",
        "email": "dkozlyuk@oss.nvidia.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20211018224353.3362537-5-dkozlyuk@nvidia.com/mbox/",
    "series": [
        {
            "id": 19761,
            "url": "http://patchwork.dpdk.org/api/series/19761/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=19761",
            "date": "2021-10-18T22:43:49",
            "name": "net/mlx5: implicit mempool registration",
            "version": 9,
            "mbox": "http://patchwork.dpdk.org/series/19761/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/102108/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/102108/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 342BEA0C45;\n\tTue, 19 Oct 2021 00:44:42 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 81F1C41109;\n\tTue, 19 Oct 2021 00:44:25 +0200 (CEST)",
            "from AZHDRRW-EX01.nvidia.com (azhdrrw-ex01.nvidia.com\n [20.51.104.162]) by mails.dpdk.org (Postfix) with ESMTP id 830B5410FC\n for <dev@dpdk.org>; Tue, 19 Oct 2021 00:44:20 +0200 (CEST)",
            "from NAM12-BN8-obe.outbound.protection.outlook.com (104.47.55.170)\n by mxs.oss.nvidia.com (10.13.234.36) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.2.858.15; Mon, 18 Oct 2021 15:44:19 -0700",
            "from DM3PR08CA0010.namprd08.prod.outlook.com (2603:10b6:0:52::20) by\n BY5PR12MB4872.namprd12.prod.outlook.com (2603:10b6:a03:1c4::13) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.15; Mon, 18 Oct\n 2021 22:44:16 +0000",
            "from DM6NAM11FT056.eop-nam11.prod.protection.outlook.com\n (2603:10b6:0:52:cafe::8) by DM3PR08CA0010.outlook.office365.com\n (2603:10b6:0:52::20) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.14 via Frontend\n Transport; Mon, 18 Oct 2021 22:44:16 +0000",
            "from mail.nvidia.com (216.228.112.34) by\n DM6NAM11FT056.mail.protection.outlook.com (10.13.173.99) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.4608.15 via Frontend Transport; Mon, 18 Oct 2021 22:44:16 +0000",
            "from nvidia.com (172.20.187.5) by HQMAIL107.nvidia.com\n (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Mon, 18 Oct\n 2021 22:44:14 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=UPWantyQeWAMEFIpp6O8TlqR+ad7pWgSFG6spgY0JuFHpR2vFVBcsyH7Taxz9Ogx0JLR45lYMp0r9o+wSjW8zPsmL7PiNJ53OhaZk54kinY1k/D+ItM3jqBuZPoW0EcnDjA6L0ffl+ROj0MdARKmb1fVtR9lvOdVGlMErtZRuxRd/bnaIDL1wWLE/l2Bjny4FEU+ofq0M9rYDD+tKx1PSthMWidYG26bTswPBSaqUrJGrBgTE28CZyEVZT+6lhIJ8Be0kn1+mdi6w3NiUQvT4BAdLKmMH7Z0UZ7XSzzYfDsEvJOaHfqTlUipVtqf9HH+kzYQS5ABqlcIAChtDfLlJw==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=Yo/Q8FqSGjG5FwabZu4lGF+tNsM16B7FqCv7AN3i6qc=;\n b=hKSaaf8LZckeIaSnmzVkGrAw4F3rp0WKk1xOwJmoZJ63mDXL/Xf+/ma57kX1U5Swmq8Fpii7oSv6Vmj5tqPimI045HLePvsKBgcxZAXp6q3jarqgUi3I6TsLVMk1NzyhA919BI6+bmhsifXEtekSYVkYXyfc/4Zzs7o7H2A8e1Z7gYh0OnvAl4JHWIYESoUaQHMEpz2QesJLWAb8I3IKYclpZJ13gShDdOWhaNMal7XvVvHw/O2vL19cGvA7WvpRAtPjB3X+HGsOUyPdkST3qRSdmS52MhTo/Xw4dZy/yAQoIKIGF4dq32GpQLqNLhM4o2UtBpMWvX4GaMRiOU8BBw==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.112.34) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com;\n dmarc=pass (p=quarantine sp=quarantine pct=100) action=none\n header.from=nvidia.com; dkim=none (message not signed); arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=Yo/Q8FqSGjG5FwabZu4lGF+tNsM16B7FqCv7AN3i6qc=;\n b=oIf/E8D6SCQhfb+Xk68rzQ+q0g20fmyfp+q6/L40Uwgcw8gZ5GhJtZl1owHX5HdjtPdpJ6JnK/pfttPX3CwtzSk4MFZOEejVpXb/Y5cDNZBHKH1OJ7yx2eodBsYI3wNAJFj3TJXMoPREql/g21i4FKkqWDEINWhAbBl08TkQFFtQIjUUScZvB9XT3FqSVKHvktlhZtUHr+4sqZd1PQb35fLminclGVOgNVJ/xCw1iJnkOTmpaoZnMh8wwTjS6ZuTEhepUqvGnxw8WPvnEi/HlneX9KD6eSLMsaf2NuFeMWgrDIpCEeqEsGzih3c95He9mGuinfsPXfnDBtCBhWInwQ==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.112.34)\n smtp.mailfrom=nvidia.com; dpdk.org; dkim=none (message not signed)\n header.d=none;dpdk.org; dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.112.34 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.112.34; helo=mail.nvidia.com;",
        "From": "Dmitry Kozlyuk <dkozlyuk@oss.nvidia.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Matan Azrad <matan@oss.nvidia.com>, Viacheslav Ovsiienko\n <viacheslavo@oss.nvidia.com>",
        "Date": "Tue, 19 Oct 2021 01:43:53 +0300",
        "Message-ID": "<20211018224353.3362537-5-dkozlyuk@nvidia.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20211018224353.3362537-1-dkozlyuk@nvidia.com>",
        "References": "<20211018144059.3303406-1-dkozlyuk@nvidia.com>\n <20211018224353.3362537-1-dkozlyuk@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[172.20.187.5]",
        "X-ClientProxiedBy": "HQMAIL111.nvidia.com (172.20.187.18) To\n HQMAIL107.nvidia.com (172.20.187.13)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "4f30a0a9-c475-428a-6240-08d99288d0c8",
        "X-MS-TrafficTypeDiagnostic": "BY5PR12MB4872:",
        "X-Microsoft-Antispam-PRVS": "\n <BY5PR12MB487253D8A7B295F1A46E0F40B9BC9@BY5PR12MB4872.namprd12.prod.outlook.com>",
        "X-MS-Oob-TLC-OOBClassifiers": "OLM:2201;",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n SRNRLm0gKoaDgxgcRJ6LA6JVXUtB9fwb5YutrFyK/7W9xC0qrzvQ8pvc+aai6l+n0kaKBUOeE+dlyemqiBNMcrnkqj7ccCId28lG56fQSd4+OxnuWCv2LCdxxULrr8PAWQs8VLTm4A9Vy1pRHIMIuWOHdWzPxWNdmyoUR9Sqrar+OrDQv5NM2DFjqOg1YPIlB/9XcfB96YnNrfD9XBZlxtBHrTABKJzIOyOwCkGIwBwqfPB+W3APCvW3YR8pWYWkIcVdsI4g+r+MA/k5KvMBuztMH7c1LHrNxkNrF6yFPSc9C2QRgAC5/EUKbS+GK8IxgHMpbP3QvClBia6B2DHKehNrBSGkkgieY4qqD5BKtM1TEwZBZWAik1HCjp6jbdpuRwGS1m2+oNhR10mJKur/SLSFZjCBiKD5JyY0GJJEglk81iTpQgVDwTh0O7Mw9iSEciIw42AuS/vBp55l0ERS1TpYmvoCElnC9PAKHa8d4OvFhO/JhXKAk15H7mbCHu+UurQ7SuqAOcXeHYLXVMT/468AglybV09pYHbXvqVhWtsz94d3+VJ29HtyN8E2zx00PeXq5BytUVErkB6onjHa2inHCJki0ZuESdWqreENPehQWj6FGBnBgqynIQkPknvtH7qfovW80SgupBs6y8XA99eqYoEE+dzMAsASAIfb3vIcUIGPJXykXPPklI6u9EYVr4JAB0YkykdLK+APVp8UfCQ6oK18iTxRZXk24CxZWhI=",
        "X-Forefront-Antispam-Report": "CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE;\n SFS:(4636009)(46966006)(36840700001)(8936002)(508600001)(356005)(47076005)(6916009)(36906005)(5660300002)(70206006)(2616005)(2906002)(83380400001)(1076003)(82310400003)(107886003)(426003)(4326008)(186003)(55016002)(7696005)(36860700001)(30864003)(54906003)(70586007)(336012)(8676002)(7636003)(316002)(36756003)(26005)(6286002)(6666004)(86362001)(16526019)(309714004);\n DIR:OUT; SFP:1101;",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "18 Oct 2021 22:44:16.1698 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 4f30a0a9-c475-428a-6240-08d99288d0c8",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n DM6NAM11FT056.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "BY5PR12MB4872",
        "Subject": "[dpdk-dev] [PATCH v9 4/4] net/mlx5: support mempool registration",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "When the first port in a given protection domain (PD) starts,\ninstall a mempool event callback for this PD and register all existing\nmemory regions (MR) for it. When the last port in a PD closes,\nremove the callback and unregister all mempools for this PD.\nThis behavior can be switched off with a new devarg: mr_mempool_reg_en.\n\nOn TX slow path, i.e. when an MR key for the address of the buffer\nto send is not in the local cache, first try to retrieve it from\nthe database of registered mempools. Supported are direct and indirect\nmbufs, as well as externally-attached ones from MLX5 MPRQ feature.\nLookup in the database of non-mempool memory is used as the last resort.\n\nRX mempools are registered regardless of the devarg value.\nOn RX data path only the local cache and the mempool database is used.\nIf implicit mempool registration is disabled, these mempools\nare unregistered at port stop, releasing the MRs.\n\nSigned-off-by: Dmitry Kozlyuk <dkozlyuk@nvidia.com>\nAcked-by: Matan Azrad <matan@nvidia.com>\n---\n doc/guides/nics/mlx5.rst               |  13 +++\n doc/guides/rel_notes/release_21_11.rst |   6 +\n drivers/net/mlx5/linux/mlx5_mp_os.c    |  44 +++++++\n drivers/net/mlx5/linux/mlx5_os.c       |   4 +-\n drivers/net/mlx5/mlx5.c                | 152 +++++++++++++++++++++++++\n drivers/net/mlx5/mlx5.h                |  10 ++\n drivers/net/mlx5/mlx5_mr.c             | 120 +++++--------------\n drivers/net/mlx5/mlx5_mr.h             |   2 -\n drivers/net/mlx5/mlx5_rx.h             |  21 ++--\n drivers/net/mlx5/mlx5_rxq.c            |  13 +++\n drivers/net/mlx5/mlx5_trigger.c        |  77 +++++++++++--\n drivers/net/mlx5/windows/mlx5_os.c     |   1 +\n 12 files changed, 347 insertions(+), 116 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst\nindex bae73f42d8..106e32e1c4 100644\n--- a/doc/guides/nics/mlx5.rst\n+++ b/doc/guides/nics/mlx5.rst\n@@ -1001,6 +1001,19 @@ Driver options\n \n   Enabled by default.\n \n+- ``mr_mempool_reg_en`` parameter [int]\n+\n+  A nonzero value enables implicit registration of DMA memory of all mempools\n+  except those having ``MEMPOOL_F_NON_IO``. This flag is set automatically\n+  for mempools populated with non-contiguous objects or those without IOVA.\n+  The effect is that when a packet from a mempool is transmitted,\n+  its memory is already registered for DMA in the PMD and no registration\n+  will happen on the data path. The tradeoff is extra work on the creation\n+  of each mempool and increased HW resource use if some mempools\n+  are not used with MLX5 devices.\n+\n+  Enabled by default.\n+\n - ``representor`` parameter [list]\n \n   This parameter can be used to instantiate DPDK Ethernet devices from\ndiff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst\nindex f6bb5adeff..4d3374f7e7 100644\n--- a/doc/guides/rel_notes/release_21_11.rst\n+++ b/doc/guides/rel_notes/release_21_11.rst\n@@ -167,6 +167,12 @@ New Features\n   * Added tests to verify tunnel header verification in IPsec inbound.\n   * Added tests to verify inner checksum.\n \n+* **Updated Mellanox mlx5 driver.**\n+\n+  Updated the Mellanox mlx5 driver with new features and improvements, including:\n+\n+  * Added implicit mempool registration to avoid data path hiccups (opt-out).\n+\n \n Removed Items\n -------------\ndiff --git a/drivers/net/mlx5/linux/mlx5_mp_os.c b/drivers/net/mlx5/linux/mlx5_mp_os.c\nindex 3a4aa766f8..d2ac375a47 100644\n--- a/drivers/net/mlx5/linux/mlx5_mp_os.c\n+++ b/drivers/net/mlx5/linux/mlx5_mp_os.c\n@@ -20,6 +20,45 @@\n #include \"mlx5_tx.h\"\n #include \"mlx5_utils.h\"\n \n+/**\n+ * Handle a port-agnostic message.\n+ *\n+ * @return\n+ *   0 on success, 1 when message is not port-agnostic, (-1) on error.\n+ */\n+static int\n+mlx5_mp_os_handle_port_agnostic(const struct rte_mp_msg *mp_msg,\n+\t\t\t\tconst void *peer)\n+{\n+\tstruct rte_mp_msg mp_res;\n+\tstruct mlx5_mp_param *res = (struct mlx5_mp_param *)mp_res.param;\n+\tconst struct mlx5_mp_param *param =\n+\t\t(const struct mlx5_mp_param *)mp_msg->param;\n+\tconst struct mlx5_mp_arg_mempool_reg *mpr;\n+\tstruct mlx5_mp_id mp_id;\n+\n+\tswitch (param->type) {\n+\tcase MLX5_MP_REQ_MEMPOOL_REGISTER:\n+\t\tmlx5_mp_id_init(&mp_id, param->port_id);\n+\t\tmp_init_msg(&mp_id, &mp_res, param->type);\n+\t\tmpr = &param->args.mempool_reg;\n+\t\tres->result = mlx5_mr_mempool_register(mpr->share_cache,\n+\t\t\t\t\t\t       mpr->pd, mpr->mempool,\n+\t\t\t\t\t\t       NULL);\n+\t\treturn rte_mp_reply(&mp_res, peer);\n+\tcase MLX5_MP_REQ_MEMPOOL_UNREGISTER:\n+\t\tmlx5_mp_id_init(&mp_id, param->port_id);\n+\t\tmp_init_msg(&mp_id, &mp_res, param->type);\n+\t\tmpr = &param->args.mempool_reg;\n+\t\tres->result = mlx5_mr_mempool_unregister(mpr->share_cache,\n+\t\t\t\t\t\t\t mpr->mempool, NULL);\n+\t\treturn rte_mp_reply(&mp_res, peer);\n+\tdefault:\n+\t\treturn 1;\n+\t}\n+\treturn -1;\n+}\n+\n int\n mlx5_mp_os_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)\n {\n@@ -34,6 +73,11 @@ mlx5_mp_os_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)\n \tint ret;\n \n \tMLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);\n+\t/* Port-agnostic messages. */\n+\tret = mlx5_mp_os_handle_port_agnostic(mp_msg, peer);\n+\tif (ret <= 0)\n+\t\treturn ret;\n+\t/* Port-specific messages. */\n \tif (!rte_eth_dev_is_valid_port(param->port_id)) {\n \t\trte_errno = ENODEV;\n \t\tDRV_LOG(ERR, \"port %u invalid port ID\", param->port_id);\ndiff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c\nindex 3746057673..e036ed1435 100644\n--- a/drivers/net/mlx5/linux/mlx5_os.c\n+++ b/drivers/net/mlx5/linux/mlx5_os.c\n@@ -1034,8 +1034,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \t\terr = mlx5_proc_priv_init(eth_dev);\n \t\tif (err)\n \t\t\treturn NULL;\n-\t\tmp_id.port_id = eth_dev->data->port_id;\n-\t\tstrlcpy(mp_id.name, MLX5_MP_NAME, RTE_MP_MAX_NAME_LEN);\n+\t\tmlx5_mp_id_init(&mp_id, eth_dev->data->port_id);\n \t\t/* Receive command fd from primary process */\n \t\terr = mlx5_mp_req_verbs_cmd_fd(&mp_id);\n \t\tif (err < 0)\n@@ -2133,6 +2132,7 @@ mlx5_os_config_default(struct mlx5_dev_config *config)\n \tconfig->txqs_inline = MLX5_ARG_UNSET;\n \tconfig->vf_nl_en = 1;\n \tconfig->mr_ext_memseg_en = 1;\n+\tconfig->mr_mempool_reg_en = 1;\n \tconfig->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;\n \tconfig->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;\n \tconfig->dv_esw_en = 1;\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 45ccfe2784..1e1b8b736b 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -181,6 +181,9 @@\n /* Device parameter to configure allow or prevent duplicate rules pattern. */\n #define MLX5_ALLOW_DUPLICATE_PATTERN \"allow_duplicate_pattern\"\n \n+/* Device parameter to configure implicit registration of mempool memory. */\n+#define MLX5_MR_MEMPOOL_REG_EN \"mr_mempool_reg_en\"\n+\n /* Shared memory between primary and secondary processes. */\n struct mlx5_shared_data *mlx5_shared_data;\n \n@@ -1088,6 +1091,141 @@ mlx5_alloc_rxtx_uars(struct mlx5_dev_ctx_shared *sh,\n \treturn err;\n }\n \n+/**\n+ * Unregister the mempool from the protection domain.\n+ *\n+ * @param sh\n+ *   Pointer to the device shared context.\n+ * @param mp\n+ *   Mempool being unregistered.\n+ */\n+static void\n+mlx5_dev_ctx_shared_mempool_unregister(struct mlx5_dev_ctx_shared *sh,\n+\t\t\t\t       struct rte_mempool *mp)\n+{\n+\tstruct mlx5_mp_id mp_id;\n+\n+\tmlx5_mp_id_init(&mp_id, 0);\n+\tif (mlx5_mr_mempool_unregister(&sh->share_cache, mp, &mp_id) < 0)\n+\t\tDRV_LOG(WARNING, \"Failed to unregister mempool %s for PD %p: %s\",\n+\t\t\tmp->name, sh->pd, rte_strerror(rte_errno));\n+}\n+\n+/**\n+ * rte_mempool_walk() callback to register mempools\n+ * for the protection domain.\n+ *\n+ * @param mp\n+ *   The mempool being walked.\n+ * @param arg\n+ *   Pointer to the device shared context.\n+ */\n+static void\n+mlx5_dev_ctx_shared_mempool_register_cb(struct rte_mempool *mp, void *arg)\n+{\n+\tstruct mlx5_dev_ctx_shared *sh = arg;\n+\tstruct mlx5_mp_id mp_id;\n+\tint ret;\n+\n+\tmlx5_mp_id_init(&mp_id, 0);\n+\tret = mlx5_mr_mempool_register(&sh->share_cache, sh->pd, mp, &mp_id);\n+\tif (ret < 0 && rte_errno != EEXIST)\n+\t\tDRV_LOG(ERR, \"Failed to register existing mempool %s for PD %p: %s\",\n+\t\t\tmp->name, sh->pd, rte_strerror(rte_errno));\n+}\n+\n+/**\n+ * rte_mempool_walk() callback to unregister mempools\n+ * from the protection domain.\n+ *\n+ * @param mp\n+ *   The mempool being walked.\n+ * @param arg\n+ *   Pointer to the device shared context.\n+ */\n+static void\n+mlx5_dev_ctx_shared_mempool_unregister_cb(struct rte_mempool *mp, void *arg)\n+{\n+\tmlx5_dev_ctx_shared_mempool_unregister\n+\t\t\t\t((struct mlx5_dev_ctx_shared *)arg, mp);\n+}\n+\n+/**\n+ * Mempool life cycle callback for Ethernet devices.\n+ *\n+ * @param event\n+ *   Mempool life cycle event.\n+ * @param mp\n+ *   Associated mempool.\n+ * @param arg\n+ *   Pointer to a device shared context.\n+ */\n+static void\n+mlx5_dev_ctx_shared_mempool_event_cb(enum rte_mempool_event event,\n+\t\t\t\t     struct rte_mempool *mp, void *arg)\n+{\n+\tstruct mlx5_dev_ctx_shared *sh = arg;\n+\tstruct mlx5_mp_id mp_id;\n+\n+\tswitch (event) {\n+\tcase RTE_MEMPOOL_EVENT_READY:\n+\t\tmlx5_mp_id_init(&mp_id, 0);\n+\t\tif (mlx5_mr_mempool_register(&sh->share_cache, sh->pd, mp,\n+\t\t\t\t\t     &mp_id) < 0)\n+\t\t\tDRV_LOG(ERR, \"Failed to register new mempool %s for PD %p: %s\",\n+\t\t\t\tmp->name, sh->pd, rte_strerror(rte_errno));\n+\t\tbreak;\n+\tcase RTE_MEMPOOL_EVENT_DESTROY:\n+\t\tmlx5_dev_ctx_shared_mempool_unregister(sh, mp);\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ * Callback used when implicit mempool registration is disabled\n+ * in order to track Rx mempool destruction.\n+ *\n+ * @param event\n+ *   Mempool life cycle event.\n+ * @param mp\n+ *   An Rx mempool registered explicitly when the port is started.\n+ * @param arg\n+ *   Pointer to a device shared context.\n+ */\n+static void\n+mlx5_dev_ctx_shared_rx_mempool_event_cb(enum rte_mempool_event event,\n+\t\t\t\t\tstruct rte_mempool *mp, void *arg)\n+{\n+\tstruct mlx5_dev_ctx_shared *sh = arg;\n+\n+\tif (event == RTE_MEMPOOL_EVENT_DESTROY)\n+\t\tmlx5_dev_ctx_shared_mempool_unregister(sh, mp);\n+}\n+\n+int\n+mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_dev_ctx_shared *sh = priv->sh;\n+\tint ret;\n+\n+\t/* Check if we only need to track Rx mempool destruction. */\n+\tif (!priv->config.mr_mempool_reg_en) {\n+\t\tret = rte_mempool_event_callback_register\n+\t\t\t\t(mlx5_dev_ctx_shared_rx_mempool_event_cb, sh);\n+\t\treturn ret == 0 || rte_errno == EEXIST ? 0 : ret;\n+\t}\n+\t/* Callback for this shared context may be already registered. */\n+\tret = rte_mempool_event_callback_register\n+\t\t\t\t(mlx5_dev_ctx_shared_mempool_event_cb, sh);\n+\tif (ret != 0 && rte_errno != EEXIST)\n+\t\treturn ret;\n+\t/* Register mempools only once for this shared context. */\n+\tif (ret == 0)\n+\t\trte_mempool_walk(mlx5_dev_ctx_shared_mempool_register_cb, sh);\n+\treturn 0;\n+}\n+\n /**\n  * Allocate shared device context. If there is multiport device the\n  * master and representors will share this context, if there is single\n@@ -1287,6 +1425,8 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,\n void\n mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh)\n {\n+\tint ret;\n+\n \tpthread_mutex_lock(&mlx5_dev_ctx_list_mutex);\n #ifdef RTE_LIBRTE_MLX5_DEBUG\n \t/* Check the object presence in the list. */\n@@ -1307,6 +1447,15 @@ mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh)\n \tMLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);\n \tif (--sh->refcnt)\n \t\tgoto exit;\n+\t/* Stop watching for mempool events and unregister all mempools. */\n+\tret = rte_mempool_event_callback_unregister\n+\t\t\t\t(mlx5_dev_ctx_shared_mempool_event_cb, sh);\n+\tif (ret < 0 && rte_errno == ENOENT)\n+\t\tret = rte_mempool_event_callback_unregister\n+\t\t\t\t(mlx5_dev_ctx_shared_rx_mempool_event_cb, sh);\n+\tif (ret == 0)\n+\t\trte_mempool_walk(mlx5_dev_ctx_shared_mempool_unregister_cb,\n+\t\t\t\t sh);\n \t/* Remove from memory callback device list. */\n \trte_rwlock_write_lock(&mlx5_shared_data->mem_event_rwlock);\n \tLIST_REMOVE(sh, mem_event_cb);\n@@ -1997,6 +2146,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque)\n \t\tconfig->decap_en = !!tmp;\n \t} else if (strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) == 0) {\n \t\tconfig->allow_duplicate_pattern = !!tmp;\n+\t} else if (strcmp(MLX5_MR_MEMPOOL_REG_EN, key) == 0) {\n+\t\tconfig->mr_mempool_reg_en = !!tmp;\n \t} else {\n \t\tDRV_LOG(WARNING, \"%s: unknown parameter\", key);\n \t\trte_errno = EINVAL;\n@@ -2058,6 +2209,7 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)\n \t\tMLX5_SYS_MEM_EN,\n \t\tMLX5_DECAP_EN,\n \t\tMLX5_ALLOW_DUPLICATE_PATTERN,\n+\t\tMLX5_MR_MEMPOOL_REG_EN,\n \t\tNULL,\n \t};\n \tstruct rte_kvargs *kvlist;\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 3581414b78..fe533fcc81 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -155,6 +155,13 @@ struct mlx5_flow_dump_ack {\n /** Key string for IPC. */\n #define MLX5_MP_NAME \"net_mlx5_mp\"\n \n+/** Initialize a multi-process ID. */\n+static inline void\n+mlx5_mp_id_init(struct mlx5_mp_id *mp_id, uint16_t port_id)\n+{\n+\tmp_id->port_id = port_id;\n+\tstrlcpy(mp_id->name, MLX5_MP_NAME, RTE_MP_MAX_NAME_LEN);\n+}\n \n LIST_HEAD(mlx5_dev_list, mlx5_dev_ctx_shared);\n \n@@ -270,6 +277,8 @@ struct mlx5_dev_config {\n \tunsigned int dv_miss_info:1; /* restore packet after partial hw miss */\n \tunsigned int allow_duplicate_pattern:1;\n \t/* Allow/Prevent the duplicate rules pattern. */\n+\tunsigned int mr_mempool_reg_en:1;\n+\t/* Allow/prevent implicit mempool memory registration. */\n \tstruct {\n \t\tunsigned int enabled:1; /* Whether MPRQ is enabled. */\n \t\tunsigned int stride_num_n; /* Number of strides. */\n@@ -1498,6 +1507,7 @@ struct mlx5_dev_ctx_shared *\n mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,\n \t\t\t   const struct mlx5_dev_config *config);\n void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);\n+int mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev);\n void mlx5_free_table_hash_list(struct mlx5_priv *priv);\n int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);\n void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,\ndiff --git a/drivers/net/mlx5/mlx5_mr.c b/drivers/net/mlx5/mlx5_mr.c\nindex 44afda731f..55d27b50b9 100644\n--- a/drivers/net/mlx5/mlx5_mr.c\n+++ b/drivers/net/mlx5/mlx5_mr.c\n@@ -65,30 +65,6 @@ mlx5_mr_mem_event_cb(enum rte_mem_event event_type, const void *addr,\n \t}\n }\n \n-/**\n- * Bottom-half of LKey search on Rx.\n- *\n- * @param rxq\n- *   Pointer to Rx queue structure.\n- * @param addr\n- *   Search key.\n- *\n- * @return\n- *   Searched LKey on success, UINT32_MAX on no match.\n- */\n-uint32_t\n-mlx5_rx_addr2mr_bh(struct mlx5_rxq_data *rxq, uintptr_t addr)\n-{\n-\tstruct mlx5_rxq_ctrl *rxq_ctrl =\n-\t\tcontainer_of(rxq, struct mlx5_rxq_ctrl, rxq);\n-\tstruct mlx5_mr_ctrl *mr_ctrl = &rxq->mr_ctrl;\n-\tstruct mlx5_priv *priv = rxq_ctrl->priv;\n-\n-\treturn mlx5_mr_addr2mr_bh(priv->sh->pd, &priv->mp_id,\n-\t\t\t\t  &priv->sh->share_cache, mr_ctrl, addr,\n-\t\t\t\t  priv->config.mr_ext_memseg_en);\n-}\n-\n /**\n  * Bottom-half of LKey search on Tx.\n  *\n@@ -128,9 +104,36 @@ mlx5_tx_addr2mr_bh(struct mlx5_txq_data *txq, uintptr_t addr)\n uint32_t\n mlx5_tx_mb2mr_bh(struct mlx5_txq_data *txq, struct rte_mbuf *mb)\n {\n+\tstruct mlx5_txq_ctrl *txq_ctrl =\n+\t\tcontainer_of(txq, struct mlx5_txq_ctrl, txq);\n+\tstruct mlx5_mr_ctrl *mr_ctrl = &txq->mr_ctrl;\n+\tstruct mlx5_priv *priv = txq_ctrl->priv;\n \tuintptr_t addr = (uintptr_t)mb->buf_addr;\n \tuint32_t lkey;\n \n+\tif (priv->config.mr_mempool_reg_en) {\n+\t\tstruct rte_mempool *mp = NULL;\n+\t\tstruct mlx5_mprq_buf *buf;\n+\n+\t\tif (!RTE_MBUF_HAS_EXTBUF(mb)) {\n+\t\t\tmp = mlx5_mb2mp(mb);\n+\t\t} else if (mb->shinfo->free_cb == mlx5_mprq_buf_free_cb) {\n+\t\t\t/* Recover MPRQ mempool. */\n+\t\t\tbuf = mb->shinfo->fcb_opaque;\n+\t\t\tmp = buf->mp;\n+\t\t}\n+\t\tif (mp != NULL) {\n+\t\t\tlkey = mlx5_mr_mempool2mr_bh(&priv->sh->share_cache,\n+\t\t\t\t\t\t     mr_ctrl, mp, addr);\n+\t\t\t/*\n+\t\t\t * Lookup can only fail on invalid input, e.g. \"addr\"\n+\t\t\t * is not from \"mp\" or \"mp\" has MEMPOOL_F_NON_IO set.\n+\t\t\t */\n+\t\t\tif (lkey != UINT32_MAX)\n+\t\t\t\treturn lkey;\n+\t\t}\n+\t\t/* Fallback for generic mechanism in corner cases. */\n+\t}\n \tlkey = mlx5_tx_addr2mr_bh(txq, addr);\n \tif (lkey == UINT32_MAX && rte_errno == ENXIO) {\n \t\t/* Mempool may have externally allocated memory. */\n@@ -392,72 +395,3 @@ mlx5_tx_update_ext_mp(struct mlx5_txq_data *txq, uintptr_t addr,\n \tmlx5_mr_update_ext_mp(ETH_DEV(priv), mr_ctrl, mp);\n \treturn mlx5_tx_addr2mr_bh(txq, addr);\n }\n-\n-/* Called during rte_mempool_mem_iter() by mlx5_mr_update_mp(). */\n-static void\n-mlx5_mr_update_mp_cb(struct rte_mempool *mp __rte_unused, void *opaque,\n-\t\t     struct rte_mempool_memhdr *memhdr,\n-\t\t     unsigned mem_idx __rte_unused)\n-{\n-\tstruct mr_update_mp_data *data = opaque;\n-\tstruct rte_eth_dev *dev = data->dev;\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n-\n-\tuint32_t lkey;\n-\n-\t/* Stop iteration if failed in the previous walk. */\n-\tif (data->ret < 0)\n-\t\treturn;\n-\t/* Register address of the chunk and update local caches. */\n-\tlkey = mlx5_mr_addr2mr_bh(priv->sh->pd, &priv->mp_id,\n-\t\t\t\t  &priv->sh->share_cache, data->mr_ctrl,\n-\t\t\t\t  (uintptr_t)memhdr->addr,\n-\t\t\t\t  priv->config.mr_ext_memseg_en);\n-\tif (lkey == UINT32_MAX)\n-\t\tdata->ret = -1;\n-}\n-\n-/**\n- * Register entire memory chunks in a Mempool.\n- *\n- * @param dev\n- *   Pointer to Ethernet device.\n- * @param mr_ctrl\n- *   Pointer to per-queue MR control structure.\n- * @param mp\n- *   Pointer to registering Mempool.\n- *\n- * @return\n- *   0 on success, -1 on failure.\n- */\n-int\n-mlx5_mr_update_mp(struct rte_eth_dev *dev, struct mlx5_mr_ctrl *mr_ctrl,\n-\t\t  struct rte_mempool *mp)\n-{\n-\tstruct mr_update_mp_data data = {\n-\t\t.dev = dev,\n-\t\t.mr_ctrl = mr_ctrl,\n-\t\t.ret = 0,\n-\t};\n-\tuint32_t flags = rte_pktmbuf_priv_flags(mp);\n-\n-\tif (flags & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF) {\n-\t\t/*\n-\t\t * The pinned external buffer should be registered for DMA\n-\t\t * operations by application. The mem_list of the pool contains\n-\t\t * the list of chunks with mbuf structures w/o built-in data\n-\t\t * buffers and DMA actually does not happen there, no need\n-\t\t * to create MR for these chunks.\n-\t\t */\n-\t\treturn 0;\n-\t}\n-\tDRV_LOG(DEBUG, \"Port %u Rx queue registering mp %s \"\n-\t\t       \"having %u chunks.\", dev->data->port_id,\n-\t\t       mp->name, mp->nb_mem_chunks);\n-\trte_mempool_mem_iter(mp, mlx5_mr_update_mp_cb, &data);\n-\tif (data.ret < 0 && rte_errno == ENXIO) {\n-\t\t/* Mempool may have externally allocated memory. */\n-\t\treturn mlx5_mr_update_ext_mp(dev, mr_ctrl, mp);\n-\t}\n-\treturn data.ret;\n-}\ndiff --git a/drivers/net/mlx5/mlx5_mr.h b/drivers/net/mlx5/mlx5_mr.h\nindex 4a7fab6df2..c984e777b5 100644\n--- a/drivers/net/mlx5/mlx5_mr.h\n+++ b/drivers/net/mlx5/mlx5_mr.h\n@@ -22,7 +22,5 @@\n \n void mlx5_mr_mem_event_cb(enum rte_mem_event event_type, const void *addr,\n \t\t\t  size_t len, void *arg);\n-int mlx5_mr_update_mp(struct rte_eth_dev *dev, struct mlx5_mr_ctrl *mr_ctrl,\n-\t\t      struct rte_mempool *mp);\n \n #endif /* RTE_PMD_MLX5_MR_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_rx.h b/drivers/net/mlx5/mlx5_rx.h\nindex 2b7ad3e48b..1b00076fe7 100644\n--- a/drivers/net/mlx5/mlx5_rx.h\n+++ b/drivers/net/mlx5/mlx5_rx.h\n@@ -275,13 +275,11 @@ uint16_t mlx5_rx_burst_vec(void *dpdk_rxq, struct rte_mbuf **pkts,\n uint16_t mlx5_rx_burst_mprq_vec(void *dpdk_rxq, struct rte_mbuf **pkts,\n \t\t\t\tuint16_t pkts_n);\n \n-/* mlx5_mr.c */\n-\n-uint32_t mlx5_rx_addr2mr_bh(struct mlx5_rxq_data *rxq, uintptr_t addr);\n+static int mlx5_rxq_mprq_enabled(struct mlx5_rxq_data *rxq);\n \n /**\n- * Query LKey from a packet buffer for Rx. No need to flush local caches for Rx\n- * as mempool is pre-configured and static.\n+ * Query LKey from a packet buffer for Rx. No need to flush local caches\n+ * as the Rx mempool database entries are valid for the lifetime of the queue.\n  *\n  * @param rxq\n  *   Pointer to Rx queue structure.\n@@ -290,11 +288,14 @@ uint32_t mlx5_rx_addr2mr_bh(struct mlx5_rxq_data *rxq, uintptr_t addr);\n  *\n  * @return\n  *   Searched LKey on success, UINT32_MAX on no match.\n+ *   This function always succeeds on valid input.\n  */\n static __rte_always_inline uint32_t\n mlx5_rx_addr2mr(struct mlx5_rxq_data *rxq, uintptr_t addr)\n {\n \tstruct mlx5_mr_ctrl *mr_ctrl = &rxq->mr_ctrl;\n+\tstruct mlx5_rxq_ctrl *rxq_ctrl;\n+\tstruct rte_mempool *mp;\n \tuint32_t lkey;\n \n \t/* Linear search on MR cache array. */\n@@ -302,8 +303,14 @@ mlx5_rx_addr2mr(struct mlx5_rxq_data *rxq, uintptr_t addr)\n \t\t\t\t   MLX5_MR_CACHE_N, addr);\n \tif (likely(lkey != UINT32_MAX))\n \t\treturn lkey;\n-\t/* Take slower bottom-half (Binary Search) on miss. */\n-\treturn mlx5_rx_addr2mr_bh(rxq, addr);\n+\t/*\n+\t * Slower search in the mempool database on miss.\n+\t * During queue creation rxq->sh is not yet set, so we use rxq_ctrl.\n+\t */\n+\trxq_ctrl = container_of(rxq, struct mlx5_rxq_ctrl, rxq);\n+\tmp = mlx5_rxq_mprq_enabled(rxq) ? rxq->mprq_mp : rxq->mp;\n+\treturn mlx5_mr_mempool2mr_bh(&rxq_ctrl->priv->sh->share_cache,\n+\t\t\t\t     mr_ctrl, mp, addr);\n }\n \n #define mlx5_rx_mb2mr(rxq, mb) mlx5_rx_addr2mr(rxq, (uintptr_t)((mb)->buf_addr))\ndiff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c\nindex b68443bed5..247f36e5d7 100644\n--- a/drivers/net/mlx5/mlx5_rxq.c\n+++ b/drivers/net/mlx5/mlx5_rxq.c\n@@ -1162,6 +1162,7 @@ mlx5_mprq_alloc_mp(struct rte_eth_dev *dev)\n \tunsigned int strd_sz_n = 0;\n \tunsigned int i;\n \tunsigned int n_ibv = 0;\n+\tint ret;\n \n \tif (!mlx5_mprq_enabled(dev))\n \t\treturn 0;\n@@ -1241,6 +1242,16 @@ mlx5_mprq_alloc_mp(struct rte_eth_dev *dev)\n \t\trte_errno = ENOMEM;\n \t\treturn -rte_errno;\n \t}\n+\tret = mlx5_mr_mempool_register(&priv->sh->share_cache, priv->sh->pd,\n+\t\t\t\t       mp, &priv->mp_id);\n+\tif (ret < 0 && rte_errno != EEXIST) {\n+\t\tret = rte_errno;\n+\t\tDRV_LOG(ERR, \"port %u failed to register a mempool for Multi-Packet RQ\",\n+\t\t\tdev->data->port_id);\n+\t\trte_mempool_free(mp);\n+\t\trte_errno = ret;\n+\t\treturn -rte_errno;\n+\t}\n \tpriv->mprq_mp = mp;\n exit:\n \t/* Set mempool for each Rx queue. */\n@@ -1443,6 +1454,8 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n \t\t/* rte_errno is already set. */\n \t\tgoto error;\n \t}\n+\t/* Rx queues don't use this pointer, but we want a valid structure. */\n+\ttmpl->rxq.mr_ctrl.dev_gen_ptr = &priv->sh->share_cache.dev_gen;\n \ttmpl->socket = socket;\n \tif (dev->data->dev_conf.intr_conf.rxq)\n \t\ttmpl->irq = 1;\ndiff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c\nindex 54173bfacb..3cbf5816a1 100644\n--- a/drivers/net/mlx5/mlx5_trigger.c\n+++ b/drivers/net/mlx5/mlx5_trigger.c\n@@ -105,6 +105,59 @@ mlx5_txq_start(struct rte_eth_dev *dev)\n \treturn -rte_errno;\n }\n \n+/**\n+ * Translate the chunk address to MR key in order to put in into the cache.\n+ */\n+static void\n+mlx5_rxq_mempool_register_cb(struct rte_mempool *mp, void *opaque,\n+\t\t\t     struct rte_mempool_memhdr *memhdr,\n+\t\t\t     unsigned int idx)\n+{\n+\tstruct mlx5_rxq_data *rxq = opaque;\n+\n+\tRTE_SET_USED(mp);\n+\tRTE_SET_USED(idx);\n+\tmlx5_rx_addr2mr(rxq, (uintptr_t)memhdr->addr);\n+}\n+\n+/**\n+ * Register Rx queue mempools and fill the Rx queue cache.\n+ * This function tolerates repeated mempool registration.\n+ *\n+ * @param[in] rxq_ctrl\n+ *   Rx queue control data.\n+ *\n+ * @return\n+ *   0 on success, (-1) on failure and rte_errno is set.\n+ */\n+static int\n+mlx5_rxq_mempool_register(struct mlx5_rxq_ctrl *rxq_ctrl)\n+{\n+\tstruct mlx5_priv *priv = rxq_ctrl->priv;\n+\tstruct rte_mempool *mp;\n+\tuint32_t s;\n+\tint ret = 0;\n+\n+\tmlx5_mr_flush_local_cache(&rxq_ctrl->rxq.mr_ctrl);\n+\t/* MPRQ mempool is registered on creation, just fill the cache. */\n+\tif (mlx5_rxq_mprq_enabled(&rxq_ctrl->rxq)) {\n+\t\trte_mempool_mem_iter(rxq_ctrl->rxq.mprq_mp,\n+\t\t\t\t     mlx5_rxq_mempool_register_cb,\n+\t\t\t\t     &rxq_ctrl->rxq);\n+\t\treturn 0;\n+\t}\n+\tfor (s = 0; s < rxq_ctrl->rxq.rxseg_n; s++) {\n+\t\tmp = rxq_ctrl->rxq.rxseg[s].mp;\n+\t\tret = mlx5_mr_mempool_register(&priv->sh->share_cache,\n+\t\t\t\t\t       priv->sh->pd, mp, &priv->mp_id);\n+\t\tif (ret < 0 && rte_errno != EEXIST)\n+\t\t\treturn ret;\n+\t\trte_mempool_mem_iter(mp, mlx5_rxq_mempool_register_cb,\n+\t\t\t\t     &rxq_ctrl->rxq);\n+\t}\n+\treturn 0;\n+}\n+\n /**\n  * Stop traffic on Rx queues.\n  *\n@@ -152,18 +205,13 @@ mlx5_rxq_start(struct rte_eth_dev *dev)\n \t\tif (!rxq_ctrl)\n \t\t\tcontinue;\n \t\tif (rxq_ctrl->type == MLX5_RXQ_TYPE_STANDARD) {\n-\t\t\t/* Pre-register Rx mempools. */\n-\t\t\tif (mlx5_rxq_mprq_enabled(&rxq_ctrl->rxq)) {\n-\t\t\t\tmlx5_mr_update_mp(dev, &rxq_ctrl->rxq.mr_ctrl,\n-\t\t\t\t\t\t  rxq_ctrl->rxq.mprq_mp);\n-\t\t\t} else {\n-\t\t\t\tuint32_t s;\n-\n-\t\t\t\tfor (s = 0; s < rxq_ctrl->rxq.rxseg_n; s++)\n-\t\t\t\t\tmlx5_mr_update_mp\n-\t\t\t\t\t\t(dev, &rxq_ctrl->rxq.mr_ctrl,\n-\t\t\t\t\t\trxq_ctrl->rxq.rxseg[s].mp);\n-\t\t\t}\n+\t\t\t/*\n+\t\t\t * Pre-register the mempools. Regardless of whether\n+\t\t\t * the implicit registration is enabled or not,\n+\t\t\t * Rx mempool destruction is tracked to free MRs.\n+\t\t\t */\n+\t\t\tif (mlx5_rxq_mempool_register(rxq_ctrl) < 0)\n+\t\t\t\tgoto error;\n \t\t\tret = rxq_alloc_elts(rxq_ctrl);\n \t\t\tif (ret)\n \t\t\t\tgoto error;\n@@ -1124,6 +1172,11 @@ mlx5_dev_start(struct rte_eth_dev *dev)\n \t\t\tdev->data->port_id, strerror(rte_errno));\n \t\tgoto error;\n \t}\n+\tif (mlx5_dev_ctx_shared_mempool_subscribe(dev) != 0) {\n+\t\tDRV_LOG(ERR, \"port %u failed to subscribe for mempool life cycle: %s\",\n+\t\t\tdev->data->port_id, rte_strerror(rte_errno));\n+\t\tgoto error;\n+\t}\n \trte_wmb();\n \tdev->tx_pkt_burst = mlx5_select_tx_function(dev);\n \tdev->rx_pkt_burst = mlx5_select_rx_function(dev);\ndiff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c\nindex 26fa927039..149253d174 100644\n--- a/drivers/net/mlx5/windows/mlx5_os.c\n+++ b/drivers/net/mlx5/windows/mlx5_os.c\n@@ -1116,6 +1116,7 @@ mlx5_os_net_probe(struct rte_device *dev)\n \tdev_config.txqs_inline = MLX5_ARG_UNSET;\n \tdev_config.vf_nl_en = 0;\n \tdev_config.mr_ext_memseg_en = 1;\n+\tdev_config.mr_mempool_reg_en = 1;\n \tdev_config.mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;\n \tdev_config.mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;\n \tdev_config.dv_esw_en = 0;\n",
    "prefixes": [
        "v9",
        "4/4"
    ]
}