get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 136468,
    "url": "http://patchwork.dpdk.org/api/patches/136468/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20240207031317.32293-13-andrew.boyer@amd.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": "<20240207031317.32293-13-andrew.boyer@amd.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240207031317.32293-13-andrew.boyer@amd.com",
    "date": "2024-02-07T03:13:16",
    "name": "[v3,12/13] net/ionic: optimize device stop operation",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "666a8fa31d9b307716b106f5237846eac8c5871c",
    "submitter": {
        "id": 2861,
        "url": "http://patchwork.dpdk.org/api/people/2861/?format=api",
        "name": "Andrew Boyer",
        "email": "Andrew.Boyer@amd.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20240207031317.32293-13-andrew.boyer@amd.com/mbox/",
    "series": [
        {
            "id": 31031,
            "url": "http://patchwork.dpdk.org/api/series/31031/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=31031",
            "date": "2024-02-07T03:13:04",
            "name": "net/ionic: miscellaneous fixes and improvements",
            "version": 3,
            "mbox": "http://patchwork.dpdk.org/series/31031/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/136468/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/136468/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 EEF2F43A2A;\n\tWed,  7 Feb 2024 04:15:22 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 1C71D42E22;\n\tWed,  7 Feb 2024 04:14:36 +0100 (CET)",
            "from NAM11-BN8-obe.outbound.protection.outlook.com\n (mail-bn8nam11on2040.outbound.protection.outlook.com [40.107.236.40])\n by mails.dpdk.org (Postfix) with ESMTP id CEB2F42DD3\n for <dev@dpdk.org>; Wed,  7 Feb 2024 04:14:24 +0100 (CET)",
            "from DM6PR02CA0054.namprd02.prod.outlook.com (2603:10b6:5:177::31)\n by CH2PR12MB4135.namprd12.prod.outlook.com (2603:10b6:610:7c::22) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7270.16; Wed, 7 Feb\n 2024 03:14:23 +0000",
            "from CO1PEPF000044FB.namprd21.prod.outlook.com\n (2603:10b6:5:177:cafe::4d) by DM6PR02CA0054.outlook.office365.com\n (2603:10b6:5:177::31) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7249.36 via Frontend\n Transport; Wed, 7 Feb 2024 03:14:22 +0000",
            "from SATLEXMB04.amd.com (165.204.84.17) by\n CO1PEPF000044FB.mail.protection.outlook.com (10.167.241.201) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id\n 15.20.7292.0 via Frontend Transport; Wed, 7 Feb 2024 03:14:22 +0000",
            "from driver-dev1.pensando.io (10.180.168.240) by SATLEXMB04.amd.com\n (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Tue, 6 Feb\n 2024 21:14:19 -0600"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=hNJlUuPh9TMC7UQB5vD4Ci7fq5RUH+ma2uk2cXwYizCrm4uBWHhT/DjZs7c9HOkVRYJSpqkIGWRN/87tQoG6fJ3mE7Qc44UK36BNRCMR5wzrGrBXyVTqbuISCfYA2dDtIw3UueWl8DOodg8NfRIIhLQY5uFg51UxP79z2lYzLKI1MrEEmGRoe1mbSobdxdVJewsxKr+S+aV5ph8pfo2FAXAIKe9NKocicWGdph85iRJhQxFlT3RRVWO+WjyVw2k5HYqNna0bHF8BT/0M9sowwcMY9E/GP8ARWR+awq7TmYv//LnegWRD3p7MhJo06NlmVXBOUAWhKeJWhFknKemH/Q==",
        "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=8DSXhgzgwelg7ionxOwieFnXyNEuuP4o5FhvdpHVJxA=;\n b=CVs1p3K6gIoLHdTSAJlsJC7fz6W+lcpDPrQmAeJaRrTB6xlyOigfYIO9V+9QV1+f4OQWZ+np1easEoxxc18knVee3rqRUS9Y91MT4C5kQAvI3sL3MzxRIYEeftzIXePTPwQQUYZ/ItZCLIzLmbm+Uk7wrqIX8/cPibuulmyKfOdL/pgxtH0YQ99SpTjSqudsKSaXKHinkdRR/EnLX5j4f6zcAligva1LEu+RmnCfn0gNxTx6mKxStnlmGKBtQLKDyy1TGnqjPKIFgUH8S+kcypSSowMBdGd0HxNTUaHKbmgJvkL5Zgxk4n/OkilV7yHLuUBs1OrsGXfRSGX2Z+/yWg==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 165.204.84.17) smtp.rcpttodomain=dpdk.org smtp.mailfrom=amd.com; dmarc=pass\n (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com;\n dkim=none (message not signed); arc=none (0)",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=8DSXhgzgwelg7ionxOwieFnXyNEuuP4o5FhvdpHVJxA=;\n b=DGwYywdQtE9gxgG2un2mTJ9B6tHSDbchVaTafnLPIhjYuBmAIT4QPbc/oql9pltG42Tsfy9mPQypC/5qvaXeSMuZEeG5yv+MmyLRaWdc94VhLx7P2216bm74u/P1jzIQaq5NYnO+v1RA3mv8vhhWAGWB6fREcKUyR58eu+5i49A=",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 165.204.84.17)\n smtp.mailfrom=amd.com; dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=amd.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of amd.com designates\n 165.204.84.17 as permitted sender) receiver=protection.outlook.com;\n client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C",
        "From": "Andrew Boyer <andrew.boyer@amd.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Andrew Boyer <andrew.boyer@amd.com>",
        "Subject": "[PATCH v3 12/13] net/ionic: optimize device stop operation",
        "Date": "Tue, 6 Feb 2024 19:13:16 -0800",
        "Message-ID": "<20240207031317.32293-13-andrew.boyer@amd.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20240207031317.32293-1-andrew.boyer@amd.com>",
        "References": "<20240202193238.62669-1-andrew.boyer@amd.com>\n <20240207031317.32293-1-andrew.boyer@amd.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.180.168.240]",
        "X-ClientProxiedBy": "SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com\n (10.181.40.145)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "CO1PEPF000044FB:EE_|CH2PR12MB4135:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "a55fb12f-497f-4a18-abbd-08dc278ae1c6",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n XVIFdW8w0v/4mHnRs6809EEiMW2wJa0reShFYDbfLNOSmwly2CYOLp7cCLrQUUi/1RIiVizi+tfaHcSgHOpsUsuXBNhfSMt0HDDPqCzGFjJoGw7IL37G/DggUlmaGO7LJ426JQ9Jt4Dd9Ed0yM2FOZebGlR5PLaGlHeu6y87i+xdM6lbrw46sIrGsGsg/csZ9uX5RaJcZjTfWdXw4G6D4MxazyqSAwrbmPlqX1hVccy62hh/EBYV2BjpXTb9m22ER2HpKrefirekfh4MIvD55zAxwk+xhe4U5cuZjpsVe33ZMHWg7PzyDT6ZHLdps6+q+dcAob+kZuJA5dI1F730ySZo9oA27F8CgAgTdDu63dUC5fQ7q/Ldvwgdz12wB7ItI70D4+ZE65SPw2ITYRpYdsUu6rbUPMFkPFbNAismZ+XKu3oa2HImtcijOcspI61jHEqdrx01MgGx4LJwG+CyBPk6pnD47/sV1SFiGqRXMnBjnd6FYtAHh+2OFU+6wq9STXk4LHCaDjDeqnaaClsoOGXBrdiycaJhs7Xozv9+Fo+tYsf/X7M1omhEUS7kZ1rnN14EoTPz85+0jjF7KTF0hf7urRVBlJn80nT/nmRNXVdtg3AIjLBF2YM3BnwM5M5GjxW5M5s/4EacQmV3AmPmMtA3C9NHJwdvjaHm/QsK0MWh08hRejRShUSeNiWDVyaOBZFOeXuHg6Zs3d1lHxpxEnn0mwcWJLE07L9OQFGg/8ISM8hT39dn1ijouXqtMRgICFfEEdpo44TLJpjT+EvnuQ==",
        "X-Forefront-Antispam-Report": "CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:;\n IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE;\n SFS:(13230031)(4636009)(39860400002)(376002)(346002)(136003)(396003)(230922051799003)(82310400011)(186009)(451199024)(1800799012)(64100799003)(40470700004)(36840700001)(46966006)(41300700001)(44832011)(47076005)(70586007)(8676002)(8936002)(70206006)(2906002)(30864003)(5660300002)(86362001)(4326008)(6916009)(316002)(36756003)(36860700001)(356005)(82740400003)(478600001)(81166007)(6666004)(83380400001)(26005)(2616005)(16526019)(426003)(1076003)(336012)(40460700003)(40480700001)(36900700001);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "amd.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "07 Feb 2024 03:14:22.4444 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n a55fb12f-497f-4a18-abbd-08dc278ae1c6",
        "X-MS-Exchange-CrossTenant-Id": "3dd8961f-e488-4e60-8e11-a82d994e183d",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17];\n Helo=[SATLEXMB04.amd.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n CO1PEPF000044FB.namprd21.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "CH2PR12MB4135",
        "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": "Split the queue_stop operation into first-half and second-half helpers.\nMove the command context from the stack into each Rx/Tx queue struct.\nExpose some needed adminq interfaces.\n\nThis allows us to batch up the queue commands during dev_stop(), reducing\nthe outage window when restarting the process by about 1ms per queue.\n\nSigned-off-by: Andrew Boyer <andrew.boyer@amd.com>\n---\n drivers/net/ionic/ionic.h      |  3 ++\n drivers/net/ionic/ionic_lif.c  | 68 ++++++++++++++++++++++-------\n drivers/net/ionic/ionic_lif.h  | 12 ++++--\n drivers/net/ionic/ionic_main.c | 17 +++++++-\n drivers/net/ionic/ionic_rxtx.c | 78 ++++++++++++++++++++--------------\n drivers/net/ionic/ionic_rxtx.h | 14 +++++-\n 6 files changed, 138 insertions(+), 54 deletions(-)",
    "diff": "diff --git a/drivers/net/ionic/ionic.h b/drivers/net/ionic/ionic.h\nindex c479eaba74..cb4ea450a9 100644\n--- a/drivers/net/ionic/ionic.h\n+++ b/drivers/net/ionic/ionic.h\n@@ -83,7 +83,10 @@ struct ionic_admin_ctx {\n \tunion ionic_adminq_comp comp;\n };\n \n+int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);\n int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);\n+int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);\n+uint16_t ionic_adminq_space_avail(struct ionic_lif *lif);\n \n int ionic_dev_cmd_wait_check(struct ionic_dev *idev, unsigned long max_wait);\n int ionic_setup(struct ionic_adapter *adapter);\ndiff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c\nindex 90efcc8cbb..45317590fa 100644\n--- a/drivers/net/ionic/ionic_lif.c\n+++ b/drivers/net/ionic/ionic_lif.c\n@@ -31,11 +31,15 @@ static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);\n static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);\n \n static int\n-ionic_qcq_disable(struct ionic_qcq *qcq)\n+ionic_qcq_disable_nowait(struct ionic_qcq *qcq,\n+\t\tstruct ionic_admin_ctx *ctx)\n {\n+\tint err;\n+\n \tstruct ionic_queue *q = &qcq->q;\n \tstruct ionic_lif *lif = qcq->lif;\n-\tstruct ionic_admin_ctx ctx = {\n+\n+\t*ctx = (struct ionic_admin_ctx) {\n \t\t.pending_work = true,\n \t\t.cmd.q_control = {\n \t\t\t.opcode = IONIC_CMD_Q_CONTROL,\n@@ -45,28 +49,39 @@ ionic_qcq_disable(struct ionic_qcq *qcq)\n \t\t},\n \t};\n \n-\treturn ionic_adminq_post_wait(lif, &ctx);\n+\t/* Does not wait for command completion */\n+\terr = ionic_adminq_post(lif, ctx);\n+\tif (err)\n+\t\tctx->pending_work = false;\n+\treturn err;\n }\n \n void\n ionic_lif_stop(struct ionic_lif *lif)\n {\n-\tuint32_t i;\n+\tstruct rte_eth_dev *dev = lif->eth_dev;\n+\tuint32_t i, j, chunk;\n \n \tIONIC_PRINT_CALL();\n \n \tlif->state &= ~IONIC_LIF_F_UP;\n \n-\tfor (i = 0; i < lif->nrxqcqs; i++) {\n-\t\tstruct ionic_rx_qcq *rxq = lif->rxqcqs[i];\n-\t\tif (rxq->flags & IONIC_QCQ_F_INITED)\n-\t\t\t(void)ionic_dev_rx_queue_stop(lif->eth_dev, i);\n+\tchunk = ionic_adminq_space_avail(lif);\n+\n+\tfor (i = 0; i < lif->nrxqcqs; i += chunk) {\n+\t\tfor (j = 0; j < chunk && i + j < lif->nrxqcqs; j++)\n+\t\t\tionic_dev_rx_queue_stop_firsthalf(dev, i + j);\n+\n+\t\tfor (j = 0; j < chunk && i + j < lif->nrxqcqs; j++)\n+\t\t\tionic_dev_rx_queue_stop_secondhalf(dev, i + j);\n \t}\n \n-\tfor (i = 0; i < lif->ntxqcqs; i++) {\n-\t\tstruct ionic_tx_qcq *txq = lif->txqcqs[i];\n-\t\tif (txq->flags & IONIC_QCQ_F_INITED)\n-\t\t\t(void)ionic_dev_tx_queue_stop(lif->eth_dev, i);\n+\tfor (i = 0; i < lif->ntxqcqs; i += chunk) {\n+\t\tfor (j = 0; j < chunk && i + j < lif->ntxqcqs; j++)\n+\t\t\tionic_dev_tx_queue_stop_firsthalf(dev, i + j);\n+\n+\t\tfor (j = 0; j < chunk && i + j < lif->ntxqcqs; j++)\n+\t\t\tionic_dev_tx_queue_stop_secondhalf(dev, i + j);\n \t}\n }\n \n@@ -1240,21 +1255,42 @@ ionic_lif_rss_teardown(struct ionic_lif *lif)\n }\n \n void\n-ionic_lif_txq_deinit(struct ionic_tx_qcq *txq)\n+ionic_lif_txq_deinit_nowait(struct ionic_tx_qcq *txq)\n {\n-\tionic_qcq_disable(&txq->qcq);\n+\tionic_qcq_disable_nowait(&txq->qcq, &txq->admin_ctx);\n \n \ttxq->flags &= ~IONIC_QCQ_F_INITED;\n }\n \n void\n-ionic_lif_rxq_deinit(struct ionic_rx_qcq *rxq)\n+ionic_lif_txq_stats(struct ionic_tx_qcq *txq)\n+{\n+\tstruct ionic_tx_stats *stats = &txq->stats;\n+\n+\tIONIC_PRINT(DEBUG, \"TX queue %u pkts %ju tso %ju\",\n+\t\ttxq->qcq.q.index, stats->packets, stats->tso);\n+\tIONIC_PRINT(DEBUG, \"TX queue %u comps %ju (%ju per)\",\n+\t\ttxq->qcq.q.index, stats->comps,\n+\t\tstats->comps ? stats->packets / stats->comps : 0);\n+}\n+\n+void\n+ionic_lif_rxq_deinit_nowait(struct ionic_rx_qcq *rxq)\n {\n-\tionic_qcq_disable(&rxq->qcq);\n+\tionic_qcq_disable_nowait(&rxq->qcq, &rxq->admin_ctx);\n \n \trxq->flags &= ~IONIC_QCQ_F_INITED;\n }\n \n+void\n+ionic_lif_rxq_stats(struct ionic_rx_qcq *rxq)\n+{\n+\tstruct ionic_rx_stats *stats = &rxq->stats;\n+\n+\tIONIC_PRINT(DEBUG, \"RX queue %u pkts %ju mtod %ju\",\n+\t\trxq->qcq.q.index, stats->packets, stats->mtods);\n+}\n+\n static void\n ionic_lif_adminq_deinit(struct ionic_lif *lif)\n {\ndiff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h\nindex cac7a4583b..ee13f5b7c8 100644\n--- a/drivers/net/ionic/ionic_lif.h\n+++ b/drivers/net/ionic/ionic_lif.h\n@@ -10,7 +10,7 @@\n #include <rte_ethdev.h>\n #include <rte_ether.h>\n \n-#include \"ionic_osdep.h\"\n+#include \"ionic.h\"\n #include \"ionic_dev.h\"\n #include \"ionic_rx_filter.h\"\n \n@@ -99,6 +99,8 @@ struct ionic_rx_qcq {\n \n \t/* cacheline4+ */\n \tstruct rte_mbuf *mbs[IONIC_MBUF_BULK_ALLOC] __rte_cache_aligned;\n+\n+\tstruct ionic_admin_ctx admin_ctx;\n };\n \n struct ionic_tx_qcq {\n@@ -112,6 +114,8 @@ struct ionic_tx_qcq {\n \tuint16_t flags;\n \n \tstruct ionic_tx_stats stats;\n+\n+\tstruct ionic_admin_ctx admin_ctx;\n };\n \n #define IONIC_Q_TO_QCQ(_q)\tcontainer_of(_q, struct ionic_qcq, q)\n@@ -225,10 +229,12 @@ int ionic_tx_qcq_alloc(struct ionic_lif *lif, uint32_t socket_id,\n void ionic_qcq_free(struct ionic_qcq *qcq);\n \n int ionic_lif_rxq_init(struct ionic_rx_qcq *rxq);\n-void ionic_lif_rxq_deinit(struct ionic_rx_qcq *rxq);\n+void ionic_lif_rxq_deinit_nowait(struct ionic_rx_qcq *rxq);\n+void ionic_lif_rxq_stats(struct ionic_rx_qcq *rxq);\n \n int ionic_lif_txq_init(struct ionic_tx_qcq *txq);\n-void ionic_lif_txq_deinit(struct ionic_tx_qcq *txq);\n+void ionic_lif_txq_deinit_nowait(struct ionic_tx_qcq *txq);\n+void ionic_lif_txq_stats(struct ionic_tx_qcq *txq);\n \n int ionic_lif_rss_config(struct ionic_lif *lif, const uint16_t types,\n \tconst uint8_t *key, const uint32_t *indir);\ndiff --git a/drivers/net/ionic/ionic_main.c b/drivers/net/ionic/ionic_main.c\nindex c957d55bf9..1f24f64a33 100644\n--- a/drivers/net/ionic/ionic_main.c\n+++ b/drivers/net/ionic/ionic_main.c\n@@ -180,6 +180,12 @@ ionic_adminq_service(struct ionic_cq *cq, uint16_t cq_desc_index,\n \treturn true;\n }\n \n+uint16_t\n+ionic_adminq_space_avail(struct ionic_lif *lif)\n+{\n+\treturn ionic_q_space_avail(&lif->adminqcq->qcq.q);\n+}\n+\n /** ionic_adminq_post - Post an admin command.\n  * @lif:                Handle to lif.\n  * @cmd_ctx:            Api admin command context.\n@@ -191,7 +197,7 @@ ionic_adminq_service(struct ionic_cq *cq, uint16_t cq_desc_index,\n  *\n  * Return: zero or negative error status.\n  */\n-static int\n+int\n ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)\n {\n \tstruct ionic_queue *q = &lif->adminqcq->qcq.q;\n@@ -279,7 +285,6 @@ ionic_adminq_wait_for_completion(struct ionic_lif *lif,\n int\n ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)\n {\n-\tbool done;\n \tint err;\n \n \tIONIC_PRINT(DEBUG, \"Sending %s (%d) via the admin queue\",\n@@ -292,6 +297,14 @@ ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)\n \t\treturn err;\n \t}\n \n+\treturn ionic_adminq_wait(lif, ctx);\n+}\n+\n+int\n+ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)\n+{\n+\tbool done;\n+\n \tdone = ionic_adminq_wait_for_completion(lif, ctx,\n \t\tIONIC_DEVCMD_TIMEOUT);\n \ndiff --git a/drivers/net/ionic/ionic_rxtx.c b/drivers/net/ionic/ionic_rxtx.c\nindex d92fa1cca7..774dc596c0 100644\n--- a/drivers/net/ionic/ionic_rxtx.c\n+++ b/drivers/net/ionic/ionic_rxtx.c\n@@ -92,36 +92,40 @@ ionic_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)\n }\n \n int __rte_cold\n-ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)\n+ionic_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)\n {\n-\tstruct ionic_tx_stats *stats;\n-\tstruct ionic_tx_qcq *txq;\n+\tionic_dev_tx_queue_stop_firsthalf(dev, tx_queue_id);\n+\tionic_dev_tx_queue_stop_secondhalf(dev, tx_queue_id);\n+\n+\treturn 0;\n+}\n+\n+void __rte_cold\n+ionic_dev_tx_queue_stop_firsthalf(struct rte_eth_dev *dev,\n+\t\t\t\tuint16_t tx_queue_id)\n+{\n+\tstruct ionic_tx_qcq *txq = dev->data->tx_queues[tx_queue_id];\n \n \tIONIC_PRINT(DEBUG, \"Stopping TX queue %u\", tx_queue_id);\n \n-\ttxq = eth_dev->data->tx_queues[tx_queue_id];\n+\tdev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n \n-\teth_dev->data->tx_queue_state[tx_queue_id] =\n-\t\tRTE_ETH_QUEUE_STATE_STOPPED;\n+\tionic_lif_txq_deinit_nowait(txq);\n+}\n \n-\t/*\n-\t * Note: we should better post NOP Tx desc and wait for its completion\n-\t * before disabling Tx queue\n-\t */\n+void __rte_cold\n+ionic_dev_tx_queue_stop_secondhalf(struct rte_eth_dev *dev,\n+\t\t\t\tuint16_t tx_queue_id)\n+{\n+\tstruct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(dev);\n+\tstruct ionic_tx_qcq *txq = dev->data->tx_queues[tx_queue_id];\n \n-\tionic_lif_txq_deinit(txq);\n+\tionic_adminq_wait(lif, &txq->admin_ctx);\n \n \t/* Free all buffers from descriptor ring */\n \tionic_tx_empty(txq);\n \n-\tstats = &txq->stats;\n-\tIONIC_PRINT(DEBUG, \"TX queue %u pkts %ju tso %ju\",\n-\t\ttxq->qcq.q.index, stats->packets, stats->tso);\n-\tIONIC_PRINT(DEBUG, \"TX queue %u comps %ju (%ju per)\",\n-\t\ttxq->qcq.q.index, stats->comps,\n-\t\tstats->comps ? stats->packets / stats->comps : 0);\n-\n-\treturn 0;\n+\tionic_lif_txq_stats(txq);\n }\n \n int __rte_cold\n@@ -726,28 +730,40 @@ ionic_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)\n  * Stop Receive Units for specified queue.\n  */\n int __rte_cold\n-ionic_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)\n+ionic_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n {\n-\tuint8_t *rx_queue_state = eth_dev->data->rx_queue_state;\n-\tstruct ionic_rx_stats *stats;\n-\tstruct ionic_rx_qcq *rxq;\n+\tionic_dev_rx_queue_stop_firsthalf(dev, rx_queue_id);\n+\tionic_dev_rx_queue_stop_secondhalf(dev, rx_queue_id);\n+\n+\treturn 0;\n+}\n+\n+void __rte_cold\n+ionic_dev_rx_queue_stop_firsthalf(struct rte_eth_dev *dev,\n+\t\t\t\tuint16_t rx_queue_id)\n+{\n+\tstruct ionic_rx_qcq *rxq = dev->data->rx_queues[rx_queue_id];\n \n \tIONIC_PRINT(DEBUG, \"Stopping RX queue %u\", rx_queue_id);\n \n-\trxq = eth_dev->data->rx_queues[rx_queue_id];\n+\tdev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\n+\tionic_lif_rxq_deinit_nowait(rxq);\n+}\n \n-\trx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n+void __rte_cold\n+ionic_dev_rx_queue_stop_secondhalf(struct rte_eth_dev *dev,\n+\t\t\t\tuint16_t rx_queue_id)\n+{\n+\tstruct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(dev);\n+\tstruct ionic_rx_qcq *rxq = dev->data->rx_queues[rx_queue_id];\n \n-\tionic_lif_rxq_deinit(rxq);\n+\tionic_adminq_wait(lif, &rxq->admin_ctx);\n \n \t/* Free all buffers from descriptor ring */\n \tionic_rx_empty(rxq);\n \n-\tstats = &rxq->stats;\n-\tIONIC_PRINT(DEBUG, \"RX queue %u pkts %ju mtod %ju\",\n-\t\trxq->qcq.q.index, stats->packets, stats->mtods);\n-\n-\treturn 0;\n+\tionic_lif_rxq_stats(rxq);\n }\n \n int\ndiff --git a/drivers/net/ionic/ionic_rxtx.h b/drivers/net/ionic/ionic_rxtx.h\nindex 5348395956..7ca23178cc 100644\n--- a/drivers/net/ionic/ionic_rxtx.h\n+++ b/drivers/net/ionic/ionic_rxtx.h\n@@ -37,14 +37,24 @@ int ionic_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,\n \tconst struct rte_eth_rxconf *rx_conf, struct rte_mempool *mp);\n void ionic_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid);\n int ionic_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);\n-int ionic_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id);\n+int ionic_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);\n \n int ionic_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,\n \tuint16_t nb_desc,  uint32_t socket_id,\n \tconst struct rte_eth_txconf *tx_conf);\n void ionic_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);\n-int ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id);\n int ionic_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);\n+int ionic_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);\n+\n+/* Helpers for optimized dev_stop() */\n+void ionic_dev_rx_queue_stop_firsthalf(struct rte_eth_dev *dev,\n+\tuint16_t rx_queue_id);\n+void ionic_dev_rx_queue_stop_secondhalf(struct rte_eth_dev *dev,\n+\tuint16_t rx_queue_id);\n+void ionic_dev_tx_queue_stop_firsthalf(struct rte_eth_dev *dev,\n+\tuint16_t tx_queue_id);\n+void ionic_dev_tx_queue_stop_secondhalf(struct rte_eth_dev *dev,\n+\tuint16_t tx_queue_id);\n \n void ionic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n \tstruct rte_eth_rxq_info *qinfo);\n",
    "prefixes": [
        "v3",
        "12/13"
    ]
}