Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1353/?format=api
https://patches.dpdk.org/api/patches/1353/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/patch/CA+cr1couxWQp+UhcKrRenuEdy34SH11Z=Lr6mrAWL_OPkC5v-A@mail.gmail.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": "<CA+cr1couxWQp+UhcKrRenuEdy34SH11Z=Lr6mrAWL_OPkC5v-A@mail.gmail.com>", "list_archive_url": "https://inbox.dpdk.org/dev/CA+cr1couxWQp+UhcKrRenuEdy34SH11Z=Lr6mrAWL_OPkC5v-A@mail.gmail.com", "date": "2014-11-19T20:48:33", "name": "[dpdk-dev] Enhance KNI DPDK-app-side to be Multi-Producer/Consumer", "commit_ref": null, "pull_url": null, "state": "not-applicable", "archived": true, "hash": "dcfb4f6240fc5048051b7acc671df8cf48a042c2", "submitter": { "id": 7, "url": "https://patches.dpdk.org/api/people/7/?format=api", "name": "Robert Sanford", "email": "rsanford2@gmail.com" }, "delegate": null, "mbox": "https://patches.dpdk.org/project/dpdk/patch/CA+cr1couxWQp+UhcKrRenuEdy34SH11Z=Lr6mrAWL_OPkC5v-A@mail.gmail.com/mbox/", "series": [], "comments": "https://patches.dpdk.org/api/patches/1353/comments/", "check": "pending", "checks": "https://patches.dpdk.org/api/patches/1353/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 5B3E57E18;\n\tWed, 19 Nov 2014 21:38:09 +0100 (CET)", "from mail-vc0-f173.google.com (mail-vc0-f173.google.com\n\t[209.85.220.173]) by dpdk.org (Postfix) with ESMTP id 9AA3A6A95\n\tfor <dev@dpdk.org>; Wed, 19 Nov 2014 21:38:06 +0100 (CET)", "by mail-vc0-f173.google.com with SMTP id id10so740891vcb.32\n\tfor <dev@dpdk.org>; Wed, 19 Nov 2014 12:48:33 -0800 (PST)", "by 10.31.129.205 with HTTP; Wed, 19 Nov 2014 12:48:33 -0800 (PST)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\n\th=mime-version:in-reply-to:references:date:message-id:subject:from:to\n\t:content-type; bh=0Jsj6qg+5KrPsRlL6rWSZ+qdTh9bt42vcmvjcZulXMQ=;\n\tb=p7XLXZ1oX6BUdWRIEC3AI0UtBDbhKrjhpMKnxC42UMEu3MHxfRj2UlOLP4ZI8enOce\n\t8SNg7vhiR8/umvEj3jfZ95cGIrVcwYJPqSZpvptuk6emk1+Dhd8zzVgGgloZ8l1qFrju\n\t01xUCsgyMJoqyBI3B2SVZ/gSOJ8GEQQdoKqzxSDo2nPFq91/7SwY8lKH7SrHZoa3N/ZH\n\tM+0isyljxNnYIDGhYmzec07UJRBLQXDiO7xIFrB6e47TZ+VLvwYXaYkVoJpY8h+92fW8\n\tBTyexWdrGwnkfpy3u7lIjCjjmjzUTaZ3IV33w9rjJA+AT1spedq5zQn+WtHXcogTl3vy\n\tbrbA==", "MIME-Version": "1.0", "X-Received": "by 10.52.37.43 with SMTP id v11mr32391632vdj.3.1416430113132;\n\tWed, 19 Nov 2014 12:48:33 -0800 (PST)", "In-Reply-To": "<DFDF335405C17848924A094BC35766CF0A9B9418@SHSMSX104.ccr.corp.intel.com>", "References": "<D08BA44A.4363%rsanford@akamai.com>\n\t<DFDF335405C17848924A094BC35766CF0A9B9418@SHSMSX104.ccr.corp.intel.com>", "Date": "Wed, 19 Nov 2014 15:48:33 -0500", "Message-ID": "<CA+cr1couxWQp+UhcKrRenuEdy34SH11Z=Lr6mrAWL_OPkC5v-A@mail.gmail.com>", "From": "Robert Sanford <rsanford2@gmail.com>", "To": "\"Zhou, Danny\" <danny.zhou@intel.com>, \"dev@dpdk.org\" <dev@dpdk.org>", "Content-Type": "text/plain; charset=UTF-8", "X-Content-Filtered-By": "Mailman/MimeDel 2.1.15", "Subject": "Re: [dpdk-dev] Enhance KNI DPDK-app-side to be\n\tMulti-Producer/Consumer", "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": "Hi Danny,\n\nOn Fri, Nov 14, 2014 at 7:04 PM, Zhou, Danny <danny.zhou@intel.com> wrote:\n\n> It will be always good if you can submit the RFC patch in terms of KNI\n> optimization.\n>\n> On the other hand, do you have any perf. data to prove that your patchset\n> could improve\n> KNI performance which is the concern that most customers care about? We\n> introduced\n> multiple-threaded KNI kernel support last year, if I remember correctly,\n> the key perform\n> bottle-neck we found is the skb alloc/free and memcpy between skb and\n> mbuf. Would be\n> very happy if your patchset can approve I am wrong.\n\n\n\nThis is not an attempt to improve raw performance. Our modest goal is to\nmake librte_kni's RX/TX burst APIs multithreaded, without changing\nrte_kni.ko. In this RFC patch, we make it possible for multiple cores to\nconcurrently invoke rte_kni_tx_burst (or rte_kni_rx_burst) for the same KNI\ndevice.\n\nAt the moment, multiple cores invoking rte_kni_tx_burst for the same device\ncannot function correctly, because the rte_kni_fifo structures (memory\nshared between app and kernel driver) are single-producer, single-consumer.\nThe following patch supplements the rte_kni_fifo structure with an\nadditional structure that is private to the application, and we borrow\nlibrte_ring's MP/MC enqueue/dequeue logic.\n\nHere is a patch for 1.8. We have only tested a 1.7.1 version. Please have a\nlook and let us know whether you think something like this would be useful.\n\n--\nThanks,\nRobert\n\n\n*Signed-off-by: Robert Sanford <rsanford@akamai.com <rsanford@akamai.com>>*\n\n---\n lib/librte_kni/rte_kni.c | 21 +++++-\n lib/librte_kni/rte_kni_fifo.h | 131\n+++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 148 insertions(+), 4 deletions(-)\n\n+}", "diff": "diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c\nindex fdb7509..8009173 100644\n--- a/lib/librte_kni/rte_kni.c\n+++ b/lib/librte_kni/rte_kni.c\n@@ -76,6 +76,11 @@ struct rte_kni {\n struct rte_kni_fifo *alloc_q; /**< Allocated mbufs queue */\n struct rte_kni_fifo *free_q; /**< To be freed mbufs queue */\n\n+ struct rte_kni_fifo_multi tx_q_mc; /**< Make tx_q multi-consumer */\n+ struct rte_kni_fifo_multi alloc_q_mp;/**< Make alloc_q multi-producer */\n+ struct rte_kni_fifo_multi rx_q_mp; /**< Make rx_q multi-producer */\n+ struct rte_kni_fifo_multi free_q_mc;/**< Make free_q multi-consumer */\n+\n /* For request & response */\n struct rte_kni_fifo *req_q; /**< Request queue */\n struct rte_kni_fifo *resp_q; /**< Response queue */\n@@ -414,6 +419,11 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,\n kni_fifo_init(ctx->free_q, KNI_FIFO_COUNT_MAX);\n dev_info.free_phys = mz->phys_addr;\n\n+ kni_fifo_multi_init(&ctx->tx_q_mc, KNI_FIFO_COUNT_MAX);\n+ kni_fifo_multi_init(&ctx->alloc_q_mp, KNI_FIFO_COUNT_MAX);\n+ kni_fifo_multi_init(&ctx->rx_q_mp, KNI_FIFO_COUNT_MAX);\n+ kni_fifo_multi_init(&ctx->free_q_mc, KNI_FIFO_COUNT_MAX);\n+\n /* Request RING */\n mz = slot->m_req_q;\n ctx->req_q = mz->addr;\n@@ -557,7 +567,8 @@ rte_kni_handle_request(struct rte_kni *kni)\n unsigned\n rte_kni_tx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs, unsigned\nnum)\n {\n- unsigned ret = kni_fifo_put(kni->rx_q, (void **)mbufs, num);\n+ unsigned ret = kni_fifo_put_mp(kni->rx_q, &kni->rx_q_mp, (void **)mbufs,\n+ num);\n\n /* Get mbufs from free_q and then free them */\n kni_free_mbufs(kni);\n@@ -568,7 +579,8 @@ rte_kni_tx_burst(struct rte_kni *kni, struct rte_mbuf\n**mbufs, unsigned num)\n unsigned\n rte_kni_rx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs, unsigned\nnum)\n {\n- unsigned ret = kni_fifo_get(kni->tx_q, (void **)mbufs, num);\n+ unsigned ret = kni_fifo_get_mc(kni->tx_q, &kni->tx_q_mc,\n+ (void **)mbufs, num);\n\n /* Allocate mbufs and then put them into alloc_q */\n kni_allocate_mbufs(kni);\n@@ -582,7 +594,8 @@ kni_free_mbufs(struct rte_kni *kni)\n int i, ret;\n struct rte_mbuf *pkts[MAX_MBUF_BURST_NUM];\n\n- ret = kni_fifo_get(kni->free_q, (void **)pkts, MAX_MBUF_BURST_NUM);\n+ ret = kni_fifo_get_mc(kni->free_q, &kni->free_q_mc, (void **)pkts,\n+ MAX_MBUF_BURST_NUM);\n if (likely(ret > 0)) {\n for (i = 0; i < ret; i++)\n rte_pktmbuf_free(pkts[i]);\n@@ -629,7 +642,7 @@ kni_allocate_mbufs(struct rte_kni *kni)\n if (i <= 0)\n return;\n\n- ret = kni_fifo_put(kni->alloc_q, (void **)pkts, i);\n+ ret = kni_fifo_put_mp(kni->alloc_q, &kni->alloc_q_mp, (void **)pkts, i);\n\n /* Check if any mbufs not put into alloc_q, and then free them */\n if (ret >= 0 && ret < i && ret < MAX_MBUF_BURST_NUM) {\ndiff --git a/lib/librte_kni/rte_kni_fifo.h b/lib/librte_kni/rte_kni_fifo.h\nindex 8cb8587..7dccba2 100644\n--- a/lib/librte_kni/rte_kni_fifo.h\n+++ b/lib/librte_kni/rte_kni_fifo.h\n@@ -91,3 +91,134 @@ kni_fifo_get(struct rte_kni_fifo *fifo, void **data,\nunsigned num)\n fifo->read = new_read;\n return i;\n }\n+\n+\n+/**\n+ * Suplemental members to facilitate MP/MC access to KNI FIFOs.\n+ */\n+struct rte_kni_fifo_multi {\n+ volatile uint32_t head;\n+ volatile uint32_t tail;\n+ uint32_t mask;\n+ uint32_t size;\n+};\n+\n+/**\n+ * Initialize a kni fifo MP/MC struct.\n+ */\n+static void\n+kni_fifo_multi_init(struct rte_kni_fifo_multi *multi, unsigned size)\n+{\n+ multi->head = 0;\n+ multi->tail = 0;\n+ multi->mask = (typeof(multi->mask))(size - 1);\n+ multi->size = (typeof(multi->size))size;\n+}\n+\n+/**\n+ * Adds num elements into the fifo. Return the number actually written.\n+ *\n+ * Multiple-producer version, modeled after __rte_ring_mp_do_enqueue().\n+ */\n+static inline unsigned\n+kni_fifo_put_mp(struct rte_kni_fifo *fifo, struct rte_kni_fifo_multi *prod,\n+ void **data, unsigned n)\n+{\n+ uint32_t prod_head, prod_next;\n+ uint32_t cons_tail, free_entries;\n+ const unsigned max = n;\n+ int success;\n+ unsigned i;\n+ const uint32_t mask = prod->mask;\n+\n+ /* Move prod->head atomically. */\n+ do {\n+ /* Reset n to the initial burst count. */\n+ n = max;\n+\n+ prod_head = prod->head;\n+ cons_tail = fifo->read;\n+\n+ free_entries = (mask + cons_tail - prod_head) & mask;\n+\n+ /* Check that we have enough room in ring. */\n+ if (unlikely(n > free_entries)) {\n+ if (unlikely(free_entries == 0))\n+ return 0;\n+ n = free_entries;\n+ }\n+\n+ prod_next = (prod_head + n) & mask;\n+ success = rte_atomic32_cmpset(&prod->head, prod_head, prod_next);\n+ } while (unlikely(success == 0));\n+\n+ /* Write entries in ring. */\n+ for (i = 0; i < n; i++) {\n+ fifo->buffer[(prod_head + i) & mask] = data[i];\n+ }\n+ rte_compiler_barrier();\n+\n+ /* If there are other enqueues in progress that preceded us,\n+ * we need to wait for them to complete.\n+ */\n+ while (unlikely(prod->tail != prod_head))\n+ rte_pause();\n+\n+ prod->tail = prod_next;\n+ fifo->write = prod_next;\n+ return n;\n+}\n+\n+/**\n+ * Get up to num elements from the fifo. Return the number actully read.\n+ *\n+ * Multiple-consumer version, modeled after __rte_ring_mc_do_dequeue().\n+ */\n+static inline unsigned\n+kni_fifo_get_mc(struct rte_kni_fifo *fifo, struct rte_kni_fifo_multi *cons,\n+ void **data, unsigned n)\n+{\n+ uint32_t cons_head, prod_tail;\n+ uint32_t cons_next, entries;\n+ const unsigned max = n;\n+ int success;\n+ unsigned i;\n+ const uint32_t mask = cons->mask;\n+\n+ /* Move cons->head atomically. */\n+ do {\n+ /* Restore n as it may change every loop. */\n+ n = max;\n+\n+ cons_head = cons->head;\n+ prod_tail = fifo->write;\n+\n+ entries = (prod_tail - cons_head + mask + 1) & mask;\n+\n+ /* Set the actual entries for dequeue. */\n+ if (n > entries) {\n+ if (unlikely(entries == 0))\n+ return 0;\n+ n = entries;\n+ }\n+\n+ cons_next = (cons_head + n) & mask;\n+ success = rte_atomic32_cmpset(&cons->head, cons_head, cons_next);\n+ } while (unlikely(success == 0));\n+\n+ /* Copy entries from ring. */\n+ for (i = 0; i < n; i++) {\n+ data[i] = fifo->buffer[(cons_head + i) & mask];\n+ }\n+ rte_compiler_barrier();\n+\n+ /* If there are other dequeues in progress that preceded us,\n+ * we need to wait for them to complete.\n+ */\n+ while (unlikely(cons->tail != cons_head))\n+ rte_pause();\n+\n+ cons->tail = cons_next;\n+ fifo->read = cons_next;\n+ return n;\n", "prefixes": [ "dpdk-dev" ] }{ "id": 1353, "url": "