DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Konstantin Ananyev <konstantin.ananyev@huawei.com>
To: <dev@dpdk.org>
Cc: <wathsala.vithanage@arm.com>
Subject: [PATCH v3 1/2] ring: make soring to finalize its own stage only
Date: Fri, 17 Apr 2026 22:23:57 +0100	[thread overview]
Message-ID: <20260417212358.212692-2-konstantin.ananyev@huawei.com> (raw)
In-Reply-To: <20260417212358.212692-1-konstantin.ananyev@huawei.com>

While finalize() is MT-safe and can be called from multiple places:
from 'acquire()' for next stage or even from consumer's 'dequeue(),
doing so usually creates extra un-necessary contention and might
slow-down ring operations, especially for the cases when we have
multiple threads doing acquire/release for some stage.
Things become worse when we have single producer/consumer and multiple
workers doing acquire/release for the same ring.
So instead of calling finalize() from different places, just make
release() for given stage to always try to perform it.

Accorging to the soring_stress_autotest, for multiple workers (8+)
it reduces number of cycles spent by 1.5x-2.0x factor.
For l3fwd-like workload it improves things by ~20%.
For small number of workers didn't observe any serious change.
As another benefit - it allows to simplify the code.

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>
---
 lib/ring/soring.c | 52 ++++++++---------------------------------------
 1 file changed, 9 insertions(+), 43 deletions(-)

diff --git a/lib/ring/soring.c b/lib/ring/soring.c
index 3b90521bdb..fc7fc55a21 100644
--- a/lib/ring/soring.c
+++ b/lib/ring/soring.c
@@ -50,10 +50,8 @@
  * from current stage tail up to its head, check state[] and move stage tail
  * through elements that already are in SORING_ST_FINISH state.
  * Along with that, corresponding state[] values are reset to zero.
- * Note that 'finalize()' for given stage can be done from multiple places:
- * 'release()' for that stage or from 'acquire()' for next stage
- * even from consumer's 'dequeue()' - in case given stage is the last one.
- * So 'finalize()' has to be MT-safe and inside it we have to
+ * Note that 'finalize()' for given stage can be called from multiple threads
+ * in parallel, so 'finalize()' has to be MT-safe and inside it we have to
  * guarantee that only one thread will update state[] and stage's tail values.
  */
 
@@ -284,7 +282,7 @@ soring_dequeue(struct rte_soring *r, void *objs, void *meta,
 	uint32_t *available)
 {
 	enum rte_ring_sync_type st;
-	uint32_t entries, cons_head, cons_next, n, ns, reqn;
+	uint32_t entries, cons_head, cons_next, n, ns;
 
 	RTE_ASSERT(r != NULL && r->nb_stage > 0);
 	RTE_ASSERT(meta == NULL || r->meta != NULL);
@@ -293,22 +291,8 @@ soring_dequeue(struct rte_soring *r, void *objs, void *meta,
 	st = r->cons.ht.sync_type;
 
 	/* try to grab exactly @num elems first */
-	n = __rte_soring_move_cons_head(r, ns, num, RTE_RING_QUEUE_FIXED, st,
+	n = __rte_soring_move_cons_head(r, ns, num, behavior, st,
 			&cons_head, &cons_next, &entries);
-	if (n == 0) {
-		/* try to finalize some elems from previous stage */
-		n = __rte_soring_stage_finalize(&r->stage[ns].sht, ns,
-			r->state, r->mask, 2 * num);
-		entries += n;
-
-		/* repeat attempt to grab elems */
-		reqn = (behavior == RTE_RING_QUEUE_FIXED) ? num : 0;
-		if (entries >= reqn)
-			n = __rte_soring_move_cons_head(r, ns, num, behavior,
-				st, &cons_head, &cons_next, &entries);
-		else
-			n = 0;
-	}
 
 	/* we have some elems to consume */
 	if (n != 0) {
@@ -382,7 +366,7 @@ soring_acquire(struct rte_soring *r, void *objs, void *meta,
 	uint32_t stage, uint32_t num, enum rte_ring_queue_behavior behavior,
 	uint32_t *ftoken, uint32_t *available)
 {
-	uint32_t avail, head, idx, n, next, reqn;
+	uint32_t avail, head, idx, n, next;
 	struct soring_stage *pstg;
 	struct soring_stage_headtail *cons;
 
@@ -399,22 +383,7 @@ soring_acquire(struct rte_soring *r, void *objs, void *meta,
 
 		/* try to grab exactly @num elems */
 		n = __rte_soring_stage_move_head(cons, &pstg->ht, 0, num,
-			RTE_RING_QUEUE_FIXED, &head, &next, &avail);
-		if (n == 0) {
-			/* try to finalize some elems from previous stage */
-			n = __rte_soring_stage_finalize(&pstg->sht, stage - 1,
-				r->state, r->mask, 2 * num);
-			avail += n;
-
-			/* repeat attempt to grab elems */
-			reqn = (behavior == RTE_RING_QUEUE_FIXED) ? num : 0;
-			if (avail >= reqn)
-				n = __rte_soring_stage_move_head(cons,
-					&pstg->ht, 0, num, behavior, &head,
-					&next, &avail);
-			else
-				n = 0;
-		}
+			behavior, &head, &next, &avail);
 	}
 
 	if (n != 0) {
@@ -442,7 +411,7 @@ static __rte_always_inline void
 soring_release(struct rte_soring *r, const void *objs,
 	const void *meta, uint32_t stage, uint32_t n, uint32_t ftoken)
 {
-	uint32_t idx, pos, tail;
+	uint32_t idx, pos;
 	struct soring_stage *stg;
 	union soring_state st;
 
@@ -479,11 +448,8 @@ soring_release(struct rte_soring *r, const void *objs,
 	rte_atomic_store_explicit(&r->state[idx].raw, st.raw,
 			rte_memory_order_relaxed);
 
-	/* try to do finalize(), if appropriate */
-	tail = rte_atomic_load_explicit(&stg->sht.tail.pos,
-			rte_memory_order_relaxed);
-	if (tail == pos)
-		__rte_soring_stage_finalize(&stg->sht, stage, r->state, r->mask,
+	/* try to do finalize(), if possible */
+	__rte_soring_stage_finalize(&stg->sht, stage, r->state, r->mask,
 				r->capacity);
 }
 
-- 
2.51.0


  reply	other threads:[~2026-04-17 21:24 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-15 17:16 [PATCH v1 0/2] few improvemnts for SORING lib Konstantin Ananyev
2026-04-15 17:16 ` [PATCH v1 1/2] ring: make soring to finalize its own stage only Konstantin Ananyev
2026-04-15 17:16 ` [PATCH v1 2/2] ring: introduce peek API for soring Konstantin Ananyev
2026-04-16 19:14 ` [PATCH v2 0/2] few improvemnts for SORING lib Konstantin Ananyev
2026-04-16 19:14   ` [PATCH v2 1/2] ring: make soring to finalize its own stage only Konstantin Ananyev
2026-04-16 19:14   ` [PATCH v2 2/2] ring: introduce peek API for soring Konstantin Ananyev
2026-04-17 21:23   ` [PATCH v3 0/2] few improvemnts for SORING lib Konstantin Ananyev
2026-04-17 21:23     ` Konstantin Ananyev [this message]
2026-04-17 21:23     ` [PATCH v3 2/2] ring: introduce peek API for soring Konstantin Ananyev
2026-04-18  3:28     ` [PATCH v3 0/2] few improvemnts for SORING lib Stephen Hemminger
2026-04-23  9:16     ` [PATCH v4 " Konstantin Ananyev
2026-04-23  9:16       ` [PATCH v4 1/2] ring: make soring to always finalize its own stage Konstantin Ananyev
2026-04-28 11:54         ` Morten Brørup
2026-04-23  9:16       ` [PATCH v4 2/2] ring: introduce peek API for soring Konstantin Ananyev
2026-04-28 12:56         ` Morten Brørup
2026-05-05 15:45           ` Konstantin Ananyev
2026-04-29 15:57       ` [PATCH v4 0/2] few improvemnts for SORING lib Stephen Hemminger
2026-05-05 15:47       ` [PATCH v5 " Konstantin Ananyev
2026-05-05 15:47         ` [PATCH v5 1/2] ring: make soring to always finalize its own stage Konstantin Ananyev
2026-05-05 15:47         ` [PATCH v5 2/2] ring: introduce peek API for soring Konstantin Ananyev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260417212358.212692-2-konstantin.ananyev@huawei.com \
    --to=konstantin.ananyev@huawei.com \
    --cc=dev@dpdk.org \
    --cc=wathsala.vithanage@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox