get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 17313,
    "url": "https://patches.dpdk.org/api/patches/17313/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1480436367-20749-55-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": "<1480436367-20749-55-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1480436367-20749-55-git-send-email-arybchenko@solarflare.com",
    "date": "2016-11-29T16:19:26",
    "name": "[dpdk-dev,v2,54/55] net/sfc: implement transmit path start / stop",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "8dc6c4cc726d15e106b5f304e288a524c8ebfe1b",
    "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/1480436367-20749-55-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/17313/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/17313/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id D4AB6FA9C;\n\tTue, 29 Nov 2016 17:22:32 +0100 (CET)",
            "from nbfkord-smmo01.seg.att.com (nbfkord-smmo01.seg.att.com\n\t[209.65.160.76]) by dpdk.org (Postfix) with ESMTP id 95D6C3989\n\tfor <dev@dpdk.org>; Tue, 29 Nov 2016 17:20:53 +0100 (CET)",
            "from unknown [12.187.104.26] (EHLO nbfkord-smmo01.seg.att.com)\n\tby nbfkord-smmo01.seg.att.com(mxl_mta-7.2.4-7) with ESMTP id\n\t5eaad385.2b3ecceba940.83588.00-2499.173916.nbfkord-smmo01.seg.att.com\n\t(envelope-from <arybchenko@solarflare.com>); \n\tTue, 29 Nov 2016 16:20:53 +0000 (UTC)",
            "from unknown [12.187.104.26]\n\tby nbfkord-smmo01.seg.att.com(mxl_mta-7.2.4-7) with SMTP id\n\t1eaad385.0.83400.00-2380.173809.nbfkord-smmo01.seg.att.com\n\t(envelope-from <arybchenko@solarflare.com>); \n\tTue, 29 Nov 2016 16:20:51 +0000 (UTC)",
            "from ocex03.SolarFlarecom.com (10.20.40.36) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id 15.0.1044.25; Tue, 29 Nov 2016 08:20:26 -0800",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id\n\t15.0.1044.25 via Frontend Transport; Tue, 29 Nov 2016 08:20:26 -0800",
            "from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com\n\t[10.17.10.10])\n\tby opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuATGKPMM030062; Tue, 29 Nov 2016 16:20:25 GMT",
            "from uklogin.uk.solarflarecom.com (localhost.localdomain\n\t[127.0.0.1])\n\tby uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuATGKM22021233; Tue, 29 Nov 2016 16:20:25 GMT"
        ],
        "X-MXL-Hash": [
            "583daae51b1543e2-5c8f1ca00314c1c5b703a89378195c1755713945",
            "583daae34f2e09a2-baec3f7869cdcf48745be796462c273640c17446"
        ],
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@intel.com>, Ivan Malov <ivan.malov@oktetlabs.ru>",
        "Date": "Tue, 29 Nov 2016 16:19:26 +0000",
        "Message-ID": "<1480436367-20749-55-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.2.3",
        "In-Reply-To": "<1480436367-20749-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>\n\t<1480436367-20749-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-AnalysisOut": [
            "[v=2.1 cv=UoJlQrEB c=1 sm=1 tr=0 a=8BlWFWvVlq5taO8ncb8nKg==]",
            "[:17 a=L24OOQBejmoA:10 a=pK7X0mNQAAAA:8 a=zRKbQ67AAAAA:8 a=]",
            "[tGi8hIWwYngSOYDSRCcA:9 a=PnRX5C3VXz4Wmum3:21 a=IoUBMQu_Kfu]",
            "[d883q:21 a=5HA-qpC1VU4iIGLgRoNS:22 a=PA03WX8tBzeizutn5_OT:]",
            "[22]"
        ],
        "X-Spam": "[F=0.2584158854; CM=0.500; S=0.258(2015072901)]",
        "X-MAIL-FROM": "<arybchenko@solarflare.com>",
        "X-SOURCE-IP": "[12.187.104.26]",
        "Subject": "[dpdk-dev] [PATCH v2 54/55] net/sfc: implement transmit path start\n\t/ stop",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Ivan Malov <ivan.malov@oktetlabs.ru>\n\nReviewed-by: Andy Moreton <amoreton@solarflare.com>\nSigned-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\n---\n drivers/net/sfc/sfc.c    |   8 ++\n drivers/net/sfc/sfc_ev.c |  12 ++-\n drivers/net/sfc/sfc_tx.c | 237 +++++++++++++++++++++++++++++++++++++++++++++++\n drivers/net/sfc/sfc_tx.h |  17 ++++\n 4 files changed, 271 insertions(+), 3 deletions(-)",
    "diff": "diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c\nindex 6990ccd..ef9e0d4 100644\n--- a/drivers/net/sfc/sfc.c\n+++ b/drivers/net/sfc/sfc.c\n@@ -276,10 +276,17 @@ sfc_start(struct sfc_adapter *sa)\n \tif (rc != 0)\n \t\tgoto fail_rx_start;\n \n+\trc = sfc_tx_start(sa);\n+\tif (rc != 0)\n+\t\tgoto fail_tx_start;\n+\n \tsa->state = SFC_ADAPTER_STARTED;\n \tsfc_log_init(sa, \"done\");\n \treturn 0;\n \n+fail_tx_start:\n+\tsfc_rx_stop(sa);\n+\n fail_rx_start:\n \tsfc_port_stop(sa);\n \n@@ -321,6 +328,7 @@ sfc_stop(struct sfc_adapter *sa)\n \n \tsa->state = SFC_ADAPTER_STOPPING;\n \n+\tsfc_tx_stop(sa);\n \tsfc_rx_stop(sa);\n \tsfc_port_stop(sa);\n \tsfc_ev_stop(sa);\ndiff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c\nindex eed1b52..075172a 100644\n--- a/drivers/net/sfc/sfc_ev.c\n+++ b/drivers/net/sfc/sfc_ev.c\n@@ -38,6 +38,7 @@\n #include \"sfc_log.h\"\n #include \"sfc_ev.h\"\n #include \"sfc_rx.h\"\n+#include \"sfc_tx.h\"\n \n \n /* Initial delay when waiting for event queue init complete event */\n@@ -208,10 +209,15 @@ static boolean_t\n sfc_ev_txq_flush_done(void *arg, __rte_unused uint32_t txq_hw_index)\n {\n \tstruct sfc_evq *evq = arg;\n+\tstruct sfc_txq *txq;\n \n-\tsfc_err(evq->sa, \"EVQ %u unexpected Tx flush done event\",\n-\t\tevq->evq_index);\n-\treturn B_TRUE;\n+\ttxq = evq->txq;\n+\tSFC_ASSERT(txq != NULL);\n+\tSFC_ASSERT(txq->hw_index == txq_hw_index);\n+\tSFC_ASSERT(txq->evq == evq);\n+\tsfc_tx_qflush_done(txq);\n+\n+\treturn B_FALSE;\n }\n \n static boolean_t\ndiff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c\nindex 8e042f5..3f38066 100644\n--- a/drivers/net/sfc/sfc_tx.c\n+++ b/drivers/net/sfc/sfc_tx.c\n@@ -28,10 +28,30 @@\n  */\n \n #include \"sfc.h\"\n+#include \"sfc_debug.h\"\n #include \"sfc_log.h\"\n #include \"sfc_ev.h\"\n #include \"sfc_tx.h\"\n \n+/*\n+ * Maximum number of TX queue flush attempts in case of\n+ * failure or flush timeout\n+ */\n+#define SFC_TX_QFLUSH_ATTEMPTS\t\t(3)\n+\n+/*\n+ * Time to wait between event queue polling attempts when waiting for TX\n+ * queue flush done or flush failed events\n+ */\n+#define SFC_TX_QFLUSH_POLL_WAIT_MS\t(1)\n+\n+/*\n+ * Maximum number of event queue polling attempts when waiting for TX queue\n+ * flush done or flush failed events; it defines TX queue flush attempt timeout\n+ * together with SFC_TX_QFLUSH_POLL_WAIT_MS\n+ */\n+#define SFC_TX_QFLUSH_POLL_ATTEMPTS\t(2000)\n+\n static int\n sfc_tx_qcheck_conf(struct sfc_adapter *sa,\n \t\t   const struct rte_eth_txconf *tx_conf)\n@@ -83,6 +103,36 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa,\n \treturn rc;\n }\n \n+void\n+sfc_tx_qflush_done(struct sfc_txq *txq)\n+{\n+\ttxq->state |= SFC_TXQ_FLUSHED;\n+\ttxq->state &= ~SFC_TXQ_FLUSHING;\n+}\n+\n+static void\n+sfc_tx_reap(struct sfc_txq *txq)\n+{\n+\tunsigned int    completed;\n+\n+\n+\tsfc_ev_qpoll(txq->evq);\n+\n+\tfor (completed = txq->completed;\n+\t     completed != txq->pending; completed++) {\n+\t\tstruct sfc_tx_sw_desc *txd;\n+\n+\t\ttxd = &txq->sw_ring[completed & txq->ptr_mask];\n+\n+\t\tif (txd->mbuf != NULL) {\n+\t\t\trte_pktmbuf_free(txd->mbuf);\n+\t\t\ttxd->mbuf = NULL;\n+\t\t}\n+\t}\n+\n+\ttxq->completed = completed;\n+}\n+\n int\n sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,\n \t     uint16_t nb_tx_desc, unsigned int socket_id,\n@@ -289,3 +339,190 @@ sfc_tx_fini(struct sfc_adapter *sa)\n \tsa->txq_info = NULL;\n \tsa->txq_count = 0;\n }\n+\n+int\n+sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tstruct rte_eth_dev_data *dev_data;\n+\tstruct sfc_txq_info *txq_info;\n+\tstruct sfc_txq *txq;\n+\tstruct sfc_evq *evq;\n+\tuint16_t flags;\n+\tunsigned int desc_index;\n+\tint rc = 0;\n+\n+\tsfc_log_init(sa, \"TxQ = %u\", sw_index);\n+\n+\tSFC_ASSERT(sw_index < sa->txq_count);\n+\ttxq_info = &sa->txq_info[sw_index];\n+\n+\ttxq = txq_info->txq;\n+\n+\tSFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);\n+\n+\tevq = txq->evq;\n+\n+\trc = sfc_ev_qstart(sa, evq->evq_index);\n+\tif (rc != 0)\n+\t\tgoto fail_ev_qstart;\n+\n+\t/*\n+\t * It seems that DPDK has no controls regarding IPv4 offloads,\n+\t * hence, we always enable it here\n+\t */\n+\tif ((txq->flags & ETH_TXQ_FLAGS_NOXSUMTCP) ||\n+\t    (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP))\n+\t\tflags = EFX_TXQ_CKSUM_IPV4;\n+\telse\n+\t\tflags = EFX_TXQ_CKSUM_IPV4 | EFX_TXQ_CKSUM_TCPUDP;\n+\n+\trc = efx_tx_qcreate(sa->nic, sw_index, 0, &txq->mem,\n+\t\t\t    txq_info->entries, 0 /* not used on EF10 */,\n+\t\t\t    flags, evq->common,\n+\t\t\t    &txq->common, &desc_index);\n+\tif (rc != 0)\n+\t\tgoto fail_tx_qcreate;\n+\n+\ttxq->added = txq->pending = txq->completed = desc_index;\n+\n+\tefx_tx_qenable(txq->common);\n+\n+\ttxq->state |= (SFC_TXQ_STARTED | SFC_TXQ_RUNNING);\n+\n+\t/*\n+\t * It seems to be used by DPDK for debug purposes only ('rte_ether')\n+\t */\n+\tdev_data = sa->eth_dev->data;\n+\tdev_data->tx_queue_state[sw_index] = RTE_ETH_QUEUE_STATE_STARTED;\n+\n+\treturn 0;\n+\n+fail_tx_qcreate:\n+\tsfc_ev_qstop(sa, evq->evq_index);\n+\n+fail_ev_qstart:\n+\treturn rc;\n+}\n+\n+void\n+sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tstruct rte_eth_dev_data *dev_data;\n+\tstruct sfc_txq_info *txq_info;\n+\tstruct sfc_txq *txq;\n+\tunsigned int retry_count;\n+\tunsigned int wait_count;\n+\tunsigned int txds;\n+\n+\tsfc_log_init(sa, \"TxQ = %u\", sw_index);\n+\n+\tSFC_ASSERT(sw_index < sa->txq_count);\n+\ttxq_info = &sa->txq_info[sw_index];\n+\n+\ttxq = txq_info->txq;\n+\n+\tSFC_ASSERT(txq->state & SFC_TXQ_STARTED);\n+\n+\ttxq->state &= ~SFC_TXQ_RUNNING;\n+\n+\t/*\n+\t * Retry TX queue flushing in case of flush failed or\n+\t * timeout; in the worst case it can delay for 6 seconds\n+\t */\n+\tfor (retry_count = 0;\n+\t     ((txq->state & SFC_TXQ_FLUSHED) == 0) &&\n+\t     (retry_count < SFC_TX_QFLUSH_ATTEMPTS);\n+\t     ++retry_count) {\n+\t\tif (efx_tx_qflush(txq->common) != 0) {\n+\t\t\ttxq->state |= SFC_TXQ_FLUSHING;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/*\n+\t\t * Wait for TX queue flush done or flush failed event at least\n+\t\t * SFC_TX_QFLUSH_POLL_WAIT_MS milliseconds and not more\n+\t\t * than 2 seconds (SFC_TX_QFLUSH_POLL_WAIT_MS multiplied\n+\t\t * by SFC_TX_QFLUSH_POLL_ATTEMPTS)\n+\t\t */\n+\t\twait_count = 0;\n+\t\tdo {\n+\t\t\trte_delay_ms(SFC_TX_QFLUSH_POLL_WAIT_MS);\n+\t\t\tsfc_ev_qpoll(txq->evq);\n+\t\t} while ((txq->state & SFC_TXQ_FLUSHING) &&\n+\t\t\t wait_count++ < SFC_TX_QFLUSH_POLL_ATTEMPTS);\n+\n+\t\tif (txq->state & SFC_TXQ_FLUSHING)\n+\t\t\tsfc_err(sa, \"TxQ %u flush timed out\", sw_index);\n+\n+\t\tif (txq->state & SFC_TXQ_FLUSHED)\n+\t\t\tsfc_info(sa, \"TxQ %u flushed\", sw_index);\n+\t}\n+\n+\tsfc_tx_reap(txq);\n+\n+\tfor (txds = 0; txds < txq_info->entries; txds++) {\n+\t\tif (txq->sw_ring[txds].mbuf != NULL) {\n+\t\t\trte_pktmbuf_free(txq->sw_ring[txds].mbuf);\n+\t\t\ttxq->sw_ring[txds].mbuf = NULL;\n+\t\t}\n+\t}\n+\n+\ttxq->state = SFC_TXQ_INITIALIZED;\n+\n+\tefx_tx_qdestroy(txq->common);\n+\n+\tsfc_ev_qstop(sa, txq->evq->evq_index);\n+\n+\t/*\n+\t * It seems to be used by DPDK for debug purposes only ('rte_ether')\n+\t */\n+\tdev_data = sa->eth_dev->data;\n+\tdev_data->tx_queue_state[sw_index] = RTE_ETH_QUEUE_STATE_STOPPED;\n+}\n+\n+int\n+sfc_tx_start(struct sfc_adapter *sa)\n+{\n+\tunsigned int sw_index;\n+\tint rc = 0;\n+\n+\tsfc_log_init(sa, \"txq_count = %u\", sa->txq_count);\n+\n+\trc = efx_tx_init(sa->nic);\n+\tif (rc != 0)\n+\t\tgoto fail_efx_tx_init;\n+\n+\tfor (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {\n+\t\trc = sfc_tx_qstart(sa, sw_index);\n+\t\tif (rc != 0)\n+\t\t\tgoto fail_tx_qstart;\n+\t}\n+\n+\treturn 0;\n+\n+fail_tx_qstart:\n+\twhile (sw_index-- > 0)\n+\t\tsfc_tx_qstop(sa, sw_index);\n+\n+\tefx_tx_fini(sa->nic);\n+\n+fail_efx_tx_init:\n+\tsfc_log_init(sa, \"failed (rc = %d)\", rc);\n+\treturn rc;\n+}\n+\n+void\n+sfc_tx_stop(struct sfc_adapter *sa)\n+{\n+\tunsigned int sw_index;\n+\n+\tsfc_log_init(sa, \"txq_count = %u\", sa->txq_count);\n+\n+\tsw_index = sa->txq_count;\n+\twhile (sw_index-- > 0) {\n+\t\tif (sa->txq_info[sw_index].txq != NULL)\n+\t\t\tsfc_tx_qstop(sa, sw_index);\n+\t}\n+\n+\tefx_tx_fini(sa->nic);\n+}\ndiff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h\nindex e8dd578..d74de00 100644\n--- a/drivers/net/sfc/sfc_tx.h\n+++ b/drivers/net/sfc/sfc_tx.h\n@@ -49,6 +49,14 @@ struct sfc_tx_sw_desc {\n enum sfc_txq_state_bit {\n \tSFC_TXQ_INITIALIZED_BIT = 0,\n #define SFC_TXQ_INITIALIZED\t(1 << SFC_TXQ_INITIALIZED_BIT)\n+\tSFC_TXQ_STARTED_BIT,\n+#define SFC_TXQ_STARTED\t\t(1 << SFC_TXQ_STARTED_BIT)\n+\tSFC_TXQ_RUNNING_BIT,\n+#define SFC_TXQ_RUNNING\t\t(1 << SFC_TXQ_RUNNING_BIT)\n+\tSFC_TXQ_FLUSHING_BIT,\n+#define SFC_TXQ_FLUSHING\t(1 << SFC_TXQ_FLUSHING_BIT)\n+\tSFC_TXQ_FLUSHED_BIT,\n+#define SFC_TXQ_FLUSHED\t\t(1 << SFC_TXQ_FLUSHED_BIT)\n };\n \n struct sfc_txq {\n@@ -59,6 +67,9 @@ struct sfc_txq {\n \tefx_desc_t\t\t*pend_desc;\n \tefx_txq_t\t\t*common;\n \tefsys_mem_t\t\tmem;\n+\tunsigned int\t\tadded;\n+\tunsigned int\t\tpending;\n+\tunsigned int\t\tcompleted;\n \n \tunsigned int\t\thw_index;\n \tunsigned int\t\tflags;\n@@ -83,6 +94,12 @@ int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,\n \t\t const struct rte_eth_txconf *tx_conf);\n void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);\n \n+void sfc_tx_qflush_done(struct sfc_txq *txq);\n+int sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index);\n+void sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index);\n+int sfc_tx_start(struct sfc_adapter *sa);\n+void sfc_tx_stop(struct sfc_adapter *sa);\n+\n #ifdef __cplusplus\n }\n #endif\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "54/55"
    ]
}