Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/17313/?format=api
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" ] }{ "id": 17313, "url": "