get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 78726,
    "url": "https://patches.dpdk.org/api/patches/78726/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1600949555-28043-50-git-send-email-arybchenko@solarflare.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": "<1600949555-28043-50-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1600949555-28043-50-git-send-email-arybchenko@solarflare.com",
    "date": "2020-09-24T12:12:24",
    "name": "[v3,49/60] common/sfc_efx/base: introduce states for UDP tunnel entries",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "69886c6917f7c368fb070d1c4dd6f3a4c7c9c82d",
    "submitter": {
        "id": 607,
        "url": "https://patches.dpdk.org/api/people/607/?format=api",
        "name": "Andrew Rybchenko",
        "email": "arybchenko@solarflare.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1600949555-28043-50-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [
        {
            "id": 12473,
            "url": "https://patches.dpdk.org/api/series/12473/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=12473",
            "date": "2020-09-24T12:11:40",
            "name": "common/sfc_efx: support Riverhead NIC family",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/12473/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/78726/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/78726/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id E64D4A04B1;\n\tThu, 24 Sep 2020 14:21:43 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 2BEC21E4AB;\n\tThu, 24 Sep 2020 14:14:12 +0200 (CEST)",
            "from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com\n [148.163.129.52]) by dpdk.org (Postfix) with ESMTP id BCBB71DE31\n for <dev@dpdk.org>; Thu, 24 Sep 2020 14:13:05 +0200 (CEST)",
            "from mx1-us1.ppe-hosted.com (unknown [10.7.65.61])\n by dispatch1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id\n 4B41360081 for <dev@dpdk.org>; Thu, 24 Sep 2020 12:13:05 +0000 (UTC)",
            "from us4-mdac16-10.ut7.mdlocal (unknown [10.7.65.180])\n by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 4AAC88009E\n for <dev@dpdk.org>; Thu, 24 Sep 2020 12:13:05 +0000 (UTC)",
            "from mx1-us1.ppe-hosted.com (unknown [10.7.65.200])\n by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id B71E380051\n for <dev@dpdk.org>; Thu, 24 Sep 2020 12:13:04 +0000 (UTC)",
            "from webmail.solarflare.com (uk.solarflare.com [193.34.186.16])\n (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits))\n (No client certificate requested)\n by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id\n 6C43C800060\n for <dev@dpdk.org>; Thu, 24 Sep 2020 12:13:04 +0000 (UTC)",
            "from ukex01.SolarFlarecom.com (10.17.10.4) by\n ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server (TLS) id\n 15.0.1497.2; Thu, 24 Sep 2020 13:12:48 +0100",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server id\n 15.0.1497.2 via Frontend Transport; Thu, 24 Sep 2020 13:12:48 +0100",
            "from ukv-loginhost.uk.solarflarecom.com\n (ukv-loginhost.uk.solarflarecom.com [10.17.10.39])\n by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id 08OCCmWM026084;\n Thu, 24 Sep 2020 13:12:48 +0100",
            "from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1])\n by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id 4307B1613A9;\n Thu, 24 Sep 2020 13:12:48 +0100 (BST)"
        ],
        "X-Virus-Scanned": "Proofpoint Essentials engine",
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Igor Romanov <igor.romanov@oktetlabs.ru>",
        "Date": "Thu, 24 Sep 2020 13:12:24 +0100",
        "Message-ID": "<1600949555-28043-50-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1600949555-28043-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1600764594-14752-1-git-send-email-arybchenko@solarflare.com>\n <1600949555-28043-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-TM-AS-Product-Ver": "SMEX-12.5.0.1300-8.6.1012-25674.003",
        "X-TM-AS-Result": "No-4.367700-8.000000-10",
        "X-TMASE-MatchedRID": "mtk6mLR4ImcGtA/+qkCcvbahwALW35jFm2HJN6OulOxUjspoiX02Fz5l\n m+VDBI4E8iO/r2KSQeg2f40FPbZ/PxnOUmRwH+xJExdS7WFvZWuXa+qM5O1u0YdfRwNmJj4N5nk\n afbcB4Nm4D18UeHIvPLCBwcM2jkC0IeFIFB+CV+wD2WXLXdz+AYLsLasl5ROhuSti1BoHqPYzIX\n glVkrDs486iamxeiiIz1IDSApLCdolz4C9OtA2ezCMW7zNwFaItxIb2hZjp3uExk6c4qzx8pAaN\n p2uvngxfwquQMgd1B5OPTaCZM51XXQMGIuvFqGPW1M77Gh1ugYCn5QffvZFlbxgMf9QE2ebg6cH\n 7aDJataau/g7THWIlV2WVzVdeoHbtAOuXrON8jbw62PQq99HWdUtYzexhQ5/RjHvrQ40NxZftsN\n 7pi/PSdGzHPOlzVgYyJV1y3Bb8icd56FC8YPW7iMJO6daqdyWfS0Ip2eEHnyTitjWv6+zCBe9CQ\n aLe2PPjoczmuoPCq0tIoOU98rjnYWVALHBQ99pF1N9El+kHucrli+URwpwOgkL+7CZpNeSQwymt\n xuJ6y0=",
        "X-TM-AS-User-Approved-Sender": "Yes",
        "X-TM-AS-User-Blocked-Sender": "No",
        "X-TMASE-Result": "10--4.367700-8.000000",
        "X-TMASE-Version": "SMEX-12.5.0.1300-8.6.1012-25674.003",
        "X-MDID": "1600949585-Ge0qcKxLL1In",
        "Subject": "[dpdk-dev] [PATCH v3 49/60] common/sfc_efx/base: introduce states\n\tfor UDP tunnel entries",
        "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 <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": "From: Igor Romanov <igor.romanov@oktetlabs.ru>\n\nUDP tunnel reconfigure operation takes UDP tunnel table, which contains\nentries that need to be applied to HW. This approach does not retain\ninformation about what entries were removed or added, which is required\nfor Riverhead.\n\nAdd states to the table entries to indicate add or remove operations.\nOn tunnel reconfiguration added and removed entries become busy to\nindicate that the entries are currently configured and to prevent add or\nremove operations from other threads. After tunnel reconfiguration is\ncomplete, the states are reset - added entries become applied and\nremoved entries are purged from the table.\n\nSigned-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\nReviewed-by: Andy Moreton <amoreton@xilinx.com>\n---\n drivers/common/sfc_efx/base/efx.h        |   9 +-\n drivers/common/sfc_efx/base/efx_impl.h   |   9 +\n drivers/common/sfc_efx/base/efx_tunnel.c | 276 +++++++++++++++++++++--\n 3 files changed, 269 insertions(+), 25 deletions(-)",
    "diff": "diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h\nindex 9f4445c099..4a0a1231dc 100644\n--- a/drivers/common/sfc_efx/base/efx.h\n+++ b/drivers/common/sfc_efx/base/efx.h\n@@ -3659,6 +3659,9 @@ efx_tunnel_config_udp_add(\n \t__in\t\tuint16_t port /* host/cpu-endian */,\n \t__in\t\tefx_tunnel_protocol_t protocol);\n \n+/*\n+ * Returns EBUSY if reconfiguration of the port is in progress in other thread.\n+ */\n LIBEFX_API\n extern\t__checkReturn\tefx_rc_t\n efx_tunnel_config_udp_remove(\n@@ -3666,8 +3669,12 @@ efx_tunnel_config_udp_remove(\n \t__in\t\tuint16_t port /* host/cpu-endian */,\n \t__in\t\tefx_tunnel_protocol_t protocol);\n \n+/*\n+ * Returns EBUSY if reconfiguration of any of the tunnel entries\n+ * is in progress in other thread.\n+ */\n LIBEFX_API\n-extern\t\t\tvoid\n+extern\t__checkReturn\tefx_rc_t\n efx_tunnel_config_clear(\n \t__in\t\tefx_nic_t *enp);\n \ndiff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h\nindex 64156de884..1ae4eeaf88 100644\n--- a/drivers/common/sfc_efx/base/efx_impl.h\n+++ b/drivers/common/sfc_efx/base/efx_impl.h\n@@ -489,9 +489,18 @@ siena_filter_tbl_clear(\n \n #if EFSYS_OPT_TUNNEL\n \n+/* State of a UDP tunnel table entry */\n+typedef enum efx_tunnel_udp_entry_state_e {\n+\tEFX_TUNNEL_UDP_ENTRY_ADDED, /* Tunnel addition is requested */\n+\tEFX_TUNNEL_UDP_ENTRY_REMOVED, /* Tunnel removal is requested */\n+\tEFX_TUNNEL_UDP_ENTRY_APPLIED, /* Tunnel is applied by HW */\n+} efx_tunnel_udp_entry_state_t;\n+\n typedef struct efx_tunnel_udp_entry_s {\n \tuint16_t\t\t\tetue_port; /* host/cpu-endian */\n \tuint16_t\t\t\tetue_protocol;\n+\tboolean_t\t\t\tetue_busy;\n+\tefx_tunnel_udp_entry_state_t\tetue_state;\n } efx_tunnel_udp_entry_t;\n \n typedef struct efx_tunnel_cfg_s {\ndiff --git a/drivers/common/sfc_efx/base/efx_tunnel.c b/drivers/common/sfc_efx/base/efx_tunnel.c\nindex 5f2186c4c8..204871e00d 100644\n--- a/drivers/common/sfc_efx/base/efx_tunnel.c\n+++ b/drivers/common/sfc_efx/base/efx_tunnel.c\n@@ -7,6 +7,43 @@\n #include \"efx.h\"\n #include \"efx_impl.h\"\n \n+/*\n+ * State diagram of the UDP tunnel table entries\n+ * (efx_tunnel_udp_entry_state_t and busy flag):\n+ *\n+ *                             +---------+\n+ *                    +--------| APPLIED |<-------+\n+ *                    |        +---------+        |\n+ *                    |                           |\n+ *                    |                efx_tunnel_reconfigure (end)\n+ *   efx_tunnel_config_udp_remove                 |\n+ *                    |                    +------------+\n+ *                    v                    | BUSY ADDED |\n+ *               +---------+               +------------+\n+ *               | REMOVED |                      ^\n+ *               +---------+                      |\n+ *                    |               efx_tunnel_reconfigure (begin)\n+ *  efx_tunnel_reconfigure (begin)                |\n+ *                    |                           |\n+ *                    v                     +-----------+\n+ *            +--------------+              |   ADDED   |<---------+\n+ *            | BUSY REMOVED |              +-----------+          |\n+ *            +--------------+                    |                |\n+ *                    |              efx_tunnel_config_udp_remove  |\n+ *  efx_tunnel_reconfigure (end)                  |                |\n+ *                    |                           |                |\n+ *                    |        +---------+        |                |\n+ *                    |        |+-------+|        |                |\n+ *                    +------->|| empty ||<-------+                |\n+ *                             |+-------+|                         |\n+ *                             +---------+        efx_tunnel_config_udp_add\n+ *                                  |                              |\n+ *                                  +------------------------------+\n+ *\n+ * Note that there is no BUSY APPLIED state since removing an applied entry\n+ * should not be blocked by ongoing reconfiguration in another thread -\n+ * reconfiguration will remove only busy entries.\n+ */\n \n #if EFSYS_OPT_TUNNEL\n \n@@ -36,6 +73,24 @@ static const efx_tunnel_ops_t\t__efx_tunnel_ef10_ops = {\n };\n #endif /* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */\n \n+/* Indicates that an entry is to be set */\n+static\t__checkReturn\t\tboolean_t\n+ef10_entry_staged(\n+\t__in\t\t\tefx_tunnel_udp_entry_t *entry)\n+{\n+\tswitch (entry->etue_state) {\n+\tcase EFX_TUNNEL_UDP_ENTRY_ADDED:\n+\t\treturn (entry->etue_busy);\n+\tcase EFX_TUNNEL_UDP_ENTRY_REMOVED:\n+\t\treturn (!entry->etue_busy);\n+\tcase EFX_TUNNEL_UDP_ENTRY_APPLIED:\n+\t\treturn (B_TRUE);\n+\tdefault:\n+\t\tEFSYS_ASSERT(0);\n+\t\treturn (B_FALSE);\n+\t}\n+}\n+\n static\t__checkReturn\t\tefx_rc_t\n efx_mcdi_set_tunnel_encap_udp_ports(\n \t__in\t\t\tefx_nic_t *enp,\n@@ -51,11 +106,17 @@ efx_mcdi_set_tunnel_encap_udp_ports(\n \tefx_rc_t rc;\n \tunsigned int i;\n \tunsigned int entries_num;\n+\tunsigned int entry;\n \n-\tif (etcp == NULL)\n-\t\tentries_num = 0;\n-\telse\n-\t\tentries_num = etcp->etc_udp_entries_num;\n+\tentries_num = 0;\n+\tif (etcp != NULL) {\n+\t\tfor (i = 0; i < etcp->etc_udp_entries_num; i++) {\n+\t\t\tif (ef10_entry_staged(&etcp->etc_udp_entries[i]) !=\n+\t\t\t    B_FALSE) {\n+\t\t\t\tentries_num++;\n+\t\t\t}\n+\t\t}\n+\t}\n \n \treq.emr_cmd = MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS;\n \treq.emr_in_buf = payload;\n@@ -73,9 +134,12 @@ efx_mcdi_set_tunnel_encap_udp_ports(\n \tMCDI_IN_SET_WORD(req, SET_TUNNEL_ENCAP_UDP_PORTS_IN_NUM_ENTRIES,\n \t    entries_num);\n \n-\tfor (i = 0; i < entries_num; ++i) {\n+\tfor (i = 0, entry = 0; entry < entries_num; ++entry, ++i) {\n \t\tuint16_t mcdi_udp_protocol;\n \n+\t\twhile (ef10_entry_staged(&etcp->etc_udp_entries[i]) == B_FALSE)\n+\t\t\ti++;\n+\n \t\tswitch (etcp->etc_udp_entries[i].etue_protocol) {\n \t\tcase EFX_TUNNEL_PROTOCOL_VXLAN:\n \t\t\tmcdi_udp_protocol = TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN;\n@@ -97,7 +161,7 @@ efx_mcdi_set_tunnel_encap_udp_ports(\n \t\t    TUNNEL_ENCAP_UDP_PORT_ENTRY_LEN);\n \t\tEFX_POPULATE_DWORD_2(\n \t\t    MCDI_IN2(req, efx_dword_t,\n-\t\t\tSET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES)[i],\n+\t\t\tSET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES)[entry],\n \t\t    TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT,\n \t\t    etcp->etc_udp_entries[i].etue_port,\n \t\t    TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL,\n@@ -230,7 +294,8 @@ efx_tunnel_config_find_udp_tunnel_entry(\n \tfor (i = 0; i < etcp->etc_udp_entries_num; ++i) {\n \t\tefx_tunnel_udp_entry_t *p = &etcp->etc_udp_entries[i];\n \n-\t\tif (p->etue_port == port) {\n+\t\tif (p->etue_port == port &&\n+\t\t    p->etue_state != EFX_TUNNEL_UDP_ENTRY_REMOVED) {\n \t\t\t*entryp = i;\n \t\t\treturn (0);\n \t\t}\n@@ -281,6 +346,8 @@ efx_tunnel_config_udp_add(\n \tetcp->etc_udp_entries[etcp->etc_udp_entries_num].etue_port = port;\n \tetcp->etc_udp_entries[etcp->etc_udp_entries_num].etue_protocol =\n \t    protocol;\n+\tetcp->etc_udp_entries[etcp->etc_udp_entries_num].etue_state =\n+\t    EFX_TUNNEL_UDP_ENTRY_ADDED;\n \n \tetcp->etc_udp_entries_num++;\n \n@@ -304,6 +371,61 @@ efx_tunnel_config_udp_add(\n \treturn (rc);\n }\n \n+/*\n+ * Returns the index of the entry after the deleted one,\n+ * or one past the last entry.\n+ */\n+static\t\t\tunsigned int\n+efx_tunnel_config_udp_do_remove(\n+\t__in\t\tefx_tunnel_cfg_t *etcp,\n+\t__in\t\tunsigned int entry)\n+{\n+\tEFSYS_ASSERT3U(etcp->etc_udp_entries_num, >, 0);\n+\tetcp->etc_udp_entries_num--;\n+\n+\tif (entry < etcp->etc_udp_entries_num) {\n+\t\tmemmove(&etcp->etc_udp_entries[entry],\n+\t\t    &etcp->etc_udp_entries[entry + 1],\n+\t\t    (etcp->etc_udp_entries_num - entry) *\n+\t\t    sizeof (etcp->etc_udp_entries[0]));\n+\t}\n+\n+\tmemset(&etcp->etc_udp_entries[etcp->etc_udp_entries_num], 0,\n+\t    sizeof (etcp->etc_udp_entries[0]));\n+\n+\treturn (entry);\n+}\n+\n+/*\n+ * Returns the index of the entry after the specified one,\n+ * or one past the last entry. The index is correct whether\n+ * the specified entry was removed or not.\n+ */\n+static\t\t\tunsigned int\n+efx_tunnel_config_udp_remove_prepare(\n+\t__in\t\tefx_tunnel_cfg_t *etcp,\n+\t__in\t\tunsigned int entry)\n+{\n+\tunsigned int next = entry + 1;\n+\n+\tswitch (etcp->etc_udp_entries[entry].etue_state) {\n+\tcase EFX_TUNNEL_UDP_ENTRY_ADDED:\n+\t\tnext = efx_tunnel_config_udp_do_remove(etcp, entry);\n+\t\tbreak;\n+\tcase EFX_TUNNEL_UDP_ENTRY_REMOVED:\n+\t\tbreak;\n+\tcase EFX_TUNNEL_UDP_ENTRY_APPLIED:\n+\t\tetcp->etc_udp_entries[entry].etue_state =\n+\t\t    EFX_TUNNEL_UDP_ENTRY_REMOVED;\n+\t\tbreak;\n+\tdefault:\n+\t\tEFSYS_ASSERT(0);\n+\t\tbreak;\n+\t}\n+\n+\treturn (next);\n+}\n+\n \t__checkReturn\tefx_rc_t\n efx_tunnel_config_udp_remove(\n \t__in\t\tefx_nic_t *enp,\n@@ -323,28 +445,25 @@ efx_tunnel_config_udp_remove(\n \tif (rc != 0)\n \t\tgoto fail1;\n \n-\tif (etcp->etc_udp_entries[entry].etue_protocol != protocol) {\n-\t\trc = EINVAL;\n+\tif (etcp->etc_udp_entries[entry].etue_busy != B_FALSE) {\n+\t\trc = EBUSY;\n \t\tgoto fail2;\n \t}\n \n-\tEFSYS_ASSERT3U(etcp->etc_udp_entries_num, >, 0);\n-\tetcp->etc_udp_entries_num--;\n-\n-\tif (entry < etcp->etc_udp_entries_num) {\n-\t\tmemmove(&etcp->etc_udp_entries[entry],\n-\t\t    &etcp->etc_udp_entries[entry + 1],\n-\t\t    (etcp->etc_udp_entries_num - entry) *\n-\t\t    sizeof (etcp->etc_udp_entries[0]));\n+\tif (etcp->etc_udp_entries[entry].etue_protocol != protocol) {\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n \t}\n \n-\tmemset(&etcp->etc_udp_entries[etcp->etc_udp_entries_num], 0,\n-\t    sizeof (etcp->etc_udp_entries[0]));\n+\t(void) efx_tunnel_config_udp_remove_prepare(etcp, entry);\n \n \tEFSYS_UNLOCK(enp->en_eslp, state);\n \n \treturn (0);\n \n+fail3:\n+\tEFSYS_PROBE(fail3);\n+\n fail2:\n \tEFSYS_PROBE(fail2);\n \n@@ -355,21 +474,51 @@ efx_tunnel_config_udp_remove(\n \treturn (rc);\n }\n \n-\t\t\tvoid\n+static\t\t\tboolean_t\n+efx_tunnel_table_all_available(\n+\t__in\t\t\tefx_tunnel_cfg_t *etcp)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < etcp->etc_udp_entries_num; i++) {\n+\t\tif (etcp->etc_udp_entries[i].etue_busy != B_FALSE)\n+\t\t\treturn (B_FALSE);\n+\t}\n+\n+\treturn (B_TRUE);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n efx_tunnel_config_clear(\n \t__in\t\t\tefx_nic_t *enp)\n {\n \tefx_tunnel_cfg_t *etcp = &enp->en_tunnel_cfg;\n \tefsys_lock_state_t state;\n+\tunsigned int i;\n+\tefx_rc_t rc;\n \n \tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TUNNEL);\n \n \tEFSYS_LOCK(enp->en_eslp, state);\n \n-\tetcp->etc_udp_entries_num = 0;\n-\tmemset(etcp->etc_udp_entries, 0, sizeof (etcp->etc_udp_entries));\n+\tif (efx_tunnel_table_all_available(etcp) == B_FALSE) {\n+\t\trc = EBUSY;\n+\t\tgoto fail1;\n+\t}\n+\n+\ti = 0;\n+\twhile (i < etcp->etc_udp_entries_num)\n+\t\ti = efx_tunnel_config_udp_remove_prepare(etcp, i);\n \n \tEFSYS_UNLOCK(enp->en_eslp, state);\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\n+\treturn (rc);\n }\n \n \t__checkReturn\tefx_rc_t\n@@ -377,6 +526,12 @@ efx_tunnel_reconfigure(\n \t__in\t\tefx_nic_t *enp)\n {\n \tconst efx_tunnel_ops_t *etop = enp->en_etop;\n+\tefx_tunnel_cfg_t *etcp = &enp->en_tunnel_cfg;\n+\tefx_tunnel_udp_entry_t *entry;\n+\tboolean_t locked = B_FALSE;\n+\tefsys_lock_state_t state;\n+\tboolean_t resetting;\n+\tunsigned int i;\n \tefx_rc_t rc;\n \n \tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TUNNEL);\n@@ -386,16 +541,89 @@ efx_tunnel_reconfigure(\n \t\tgoto fail1;\n \t}\n \n-\tif ((rc = enp->en_etop->eto_reconfigure(enp)) != 0)\n+\tEFSYS_LOCK(enp->en_eslp, state);\n+\tlocked = B_TRUE;\n+\n+\tif (efx_tunnel_table_all_available(etcp) == B_FALSE) {\n+\t\trc = EBUSY;\n \t\tgoto fail2;\n+\t}\n \n-\treturn (0);\n+\tfor (i = 0; i < etcp->etc_udp_entries_num; i++) {\n+\t\tentry = &etcp->etc_udp_entries[i];\n+\t\tif (entry->etue_state != EFX_TUNNEL_UDP_ENTRY_APPLIED)\n+\t\t\tentry->etue_busy = B_TRUE;\n+\t}\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\tlocked = B_FALSE;\n+\n+\trc = enp->en_etop->eto_reconfigure(enp);\n+\tif (rc != 0 && rc != EAGAIN)\n+\t\tgoto fail3;\n+\n+\tresetting = (rc == EAGAIN) ? B_TRUE : B_FALSE;\n+\n+\tEFSYS_LOCK(enp->en_eslp, state);\n+\tlocked = B_TRUE;\n+\n+\t/*\n+\t * Delete entries marked for removal since they are no longer\n+\t * needed after successful NIC-specific reconfiguration.\n+\t * Added entries become applied because they are installed in\n+\t * the hardware.\n+\t */\n+\n+\ti = 0;\n+\twhile (i < etcp->etc_udp_entries_num) {\n+\t\tunsigned int next = i + 1;\n+\n+\t\tentry = &etcp->etc_udp_entries[i];\n+\t\tif (entry->etue_busy != B_FALSE) {\n+\t\t\tentry->etue_busy = B_FALSE;\n+\n+\t\t\tswitch (entry->etue_state) {\n+\t\t\tcase EFX_TUNNEL_UDP_ENTRY_APPLIED:\n+\t\t\t\tbreak;\n+\t\t\tcase EFX_TUNNEL_UDP_ENTRY_ADDED:\n+\t\t\t\tentry->etue_state =\n+\t\t\t\t    EFX_TUNNEL_UDP_ENTRY_APPLIED;\n+\t\t\t\tbreak;\n+\t\t\tcase EFX_TUNNEL_UDP_ENTRY_REMOVED:\n+\t\t\t\tnext = efx_tunnel_config_udp_do_remove(etcp, i);\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\tEFSYS_ASSERT(0);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\ti = next;\n+\t}\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\tlocked = B_FALSE;\n+\n+\treturn ((resetting == B_FALSE) ? 0 : EAGAIN);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+\n+\tEFSYS_ASSERT(locked == B_FALSE);\n+\tEFSYS_LOCK(enp->en_eslp, state);\n+\n+\tfor (i = 0; i < etcp->etc_udp_entries_num; i++)\n+\t\tetcp->etc_udp_entries[i].etue_busy = B_FALSE;\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n \n fail2:\n \tEFSYS_PROBE(fail2);\n \n fail1:\n \tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\tif (locked)\n+\t\tEFSYS_UNLOCK(enp->en_eslp, state);\n \n \treturn (rc);\n }\n",
    "prefixes": [
        "v3",
        "49/60"
    ]
}