From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f54.google.com (mail-wm0-f54.google.com [74.125.82.54]) by dpdk.org (Postfix) with ESMTP id F2BC02BD7 for ; Tue, 15 Mar 2016 17:58:47 +0100 (CET) Received: by mail-wm0-f54.google.com with SMTP id l124so18831872wmf.1 for ; Tue, 15 Mar 2016 09:58:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nofutznetworks-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id; bh=ap9xiE5lnuoy5GFFt9y+0yxdMQgcfn02LnZRA/mNcRI=; b=R/FUx8naKgXxi1JIOZKd+jpv58s+lgbKIcO18f8BqsW+qWRy76Av1EVJmTaOb2VVwS Tv1Ezupxc3FyljdzeF+UszbB8DSepkq256UbM1Qv6gQOFAzLHuBB6IACD0+2LLuzJBem I4qvFI1xEvXYgEhLQIP200I96cO1z8dUdh8/DnpE2tptw73ZSwkOMDO4gK8NqMEdMLCl zE1AawsmKOBjHKs8KSYZDcdeuczRAkz9SNiTpkZ7+iZNZO376KgUKGPhRvWvMlC6skqn gGRIWGdo4Hptzy8phk5nrJ4JImpRMGc5/Qz8OECK2yeIa2GKvVwkHMVQj05LW9xTyjQC pQaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=ap9xiE5lnuoy5GFFt9y+0yxdMQgcfn02LnZRA/mNcRI=; b=gUp1C19J9+BRhjmCsdDFpi9kHGMBWp/ta1ckkzL5HNpXoVQETDBPkPP/g1Z3bg0Uo2 sBBB2ynShqBuCi74VckeMeF/xfIug2YEG6GA2v3lfPl78sQBIRxm9BdkfaHtLPoA9JGl ZpYeJiROZa/CjTFJSUAIrS+6nSUY41cUQUoG0IUH3X5O5k8kc9eFN8t+jlcFJxbaBz/J BvCLbUVrHY0LfhhXZvewdI1OvgHjMGaok+GbyAweNVYlDbVNf1lO266OA7shDsFLSiy5 OSd+3qCRoiw4ftiWuOZzpz3ADWeugLk0116sJO6f+zh5QeTC9k7E5LO8y/BKZRUVfTjf fKFg== X-Gm-Message-State: AD7BkJJNF5qlvasSonXVI0nIkxf1fEIshV5X9VYAELIhb5uTuG8pZ9VdfbmXfw5Wa2GMTQ== X-Received: by 10.28.87.139 with SMTP id l133mr23831231wmb.38.1458061127783; Tue, 15 Mar 2016 09:58:47 -0700 (PDT) Received: from lap-3.nofutz.com (ppp141255097247.access.hol.gr. [141.255.97.247]) by smtp.gmail.com with ESMTPSA id v5sm21710840wmg.16.2016.03.15.09.58.46 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 15 Mar 2016 09:58:47 -0700 (PDT) From: Lazaros Koromilas To: dev@dpdk.org Date: Tue, 15 Mar 2016 18:58:45 +0200 Message-Id: <1458061125-17515-1-git-send-email-l@nofutznetworks.com> X-Mailer: git-send-email 1.9.1 Subject: [dpdk-dev] [PATCH] ring: assert on zero objects dequeue/enqueue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Mar 2016 16:58:48 -0000 Issuing a zero objects dequeue with a single consumer has no effect. Doing so with multiple consumers, can get more than one thread to succeed the compare-and-set operation and observe starvation or even deadlock in the while loop that checks for preceding dequeues. The problematic piece of code when n = 0: cons_next = cons_head + n; success = rte_atomic32_cmpset(&r->cons.head, cons_head, cons_next); The same is possible on the enqueue path. Signed-off-by: Lazaros Koromilas --- lib/librte_ring/rte_ring.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h index 943c97c..2bf9ce3 100644 --- a/lib/librte_ring/rte_ring.h +++ b/lib/librte_ring/rte_ring.h @@ -100,6 +100,7 @@ extern "C" { #include #include #include +#include #define RTE_TAILQ_RING_NAME "RTE_RING" @@ -211,6 +212,19 @@ struct rte_ring { #endif /** + * @internal Assert macro. + * @param exp + * The expression to evaluate. + */ +#define RTE_RING_ASSERT(exp) do { \ + if (!(exp)) { \ + rte_panic("line%d\t" \ + "assert \"" #exp "\" failed\n", \ + __LINE__); \ + } \ + } while (0) + +/** * Calculate the memory size needed for a ring * * This function returns the number of bytes needed for a ring, given @@ -406,6 +420,7 @@ void rte_ring_dump(FILE *f, const struct rte_ring *r); * A pointer to a table of void * pointers (objects). * @param n * The number of objects to add in the ring from the obj_table. + * Must be greater than zero. * @param behavior * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring * RTE_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring @@ -431,6 +446,8 @@ __rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table, uint32_t mask = r->prod.mask; int ret; + RTE_RING_ASSERT(n > 0); + /* move prod.head atomically */ do { /* Reset n to the initial burst count */ @@ -510,6 +527,7 @@ __rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table, * A pointer to a table of void * pointers (objects). * @param n * The number of objects to add in the ring from the obj_table. + * Must be greater than zero. * @param behavior * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring * RTE_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring @@ -533,6 +551,8 @@ __rte_ring_sp_do_enqueue(struct rte_ring *r, void * const *obj_table, uint32_t mask = r->prod.mask; int ret; + RTE_RING_ASSERT(n > 0); + prod_head = r->prod.head; cons_tail = r->cons.tail; /* The subtraction is done between two unsigned 32bits value @@ -594,6 +614,7 @@ __rte_ring_sp_do_enqueue(struct rte_ring *r, void * const *obj_table, * A pointer to a table of void * pointers (objects) that will be filled. * @param n * The number of objects to dequeue from the ring to the obj_table. + * Must be greater than zero. * @param behavior * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring * RTE_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring @@ -618,6 +639,8 @@ __rte_ring_mc_do_dequeue(struct rte_ring *r, void **obj_table, unsigned i, rep = 0; uint32_t mask = r->prod.mask; + RTE_RING_ASSERT(n > 0); + /* move cons.head atomically */ do { /* Restore n as it may change every loop */ @@ -689,6 +712,7 @@ __rte_ring_mc_do_dequeue(struct rte_ring *r, void **obj_table, * A pointer to a table of void * pointers (objects) that will be filled. * @param n * The number of objects to dequeue from the ring to the obj_table. + * Must be greater than zero. * @param behavior * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring * RTE_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring @@ -710,6 +734,8 @@ __rte_ring_sc_do_dequeue(struct rte_ring *r, void **obj_table, unsigned i; uint32_t mask = r->prod.mask; + RTE_RING_ASSERT(n > 0); + cons_head = r->cons.head; prod_tail = r->prod.tail; /* The subtraction is done between two unsigned 32bits value -- 1.9.1