DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Morten Brørup" <mb@smartsharesystems.com>
To: "Konstantin Ananyev" <konstantin.ananyev@huawei.com>, <dev@dpdk.org>
Cc: <wathsala.vithanage@arm.com>
Subject: RE: [PATCH v4 1/2] ring: make soring to always finalize its own stage
Date: Tue, 28 Apr 2026 13:54:54 +0200	[thread overview]
Message-ID: <98CBD80474FA8B44BF855DF32C47DC35F65827@smartserver.smartshare.dk> (raw)
In-Reply-To: <20260423091625.123642-2-konstantin.ananyev@huawei.com>

> From: Konstantin Ananyev [mailto:konstantin.ananyev@huawei.com]
> Sent: Thursday, 23 April 2026 11.16
> 
> SORING internal finalize() function is MT-safe and can be called from
> multiple places: from it's own stage release(), also from 'acquire()'
> for next stage or even from consumer's 'dequeue().
> But calling finalize() from not its own stage release() function
> creates extra contention and might slow-down ring operations,
> especially
> for the cases when we have multiple threads doing acquire/release
> for the same stage.
> We can't compeletely avoid calling finalize() from all these multiple
> places, as it can in some rare cases break soring behavior.
> But we can make release() for given stage to invoke it always.
> That increases number of 'finalize()' operations done from 'release()'
> for current stage, and helps to minimize number of finalize() calls
> from
> other stages, which in turn, help to reduce the contention.
> According to the soring_stress_autotest, for multiple workers (8+)
> it reduces number of cycles spent by 1.5x-1.8x factor.
> For l3fwd-like workload it improves things by ~20%.
> For small number of workers, I didn't observe any serious change.
> Note that it doesn't introduce any changes in functionality provided.
> 
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>

Good idea.
Not peeking into the tail to determine if finalize() might be omitted also makes release() cleaner.

Removing an optimization that was not really an optimization. :-)

Acked-by: Morten Brørup <mb@smartsharesystems.com>


> ---
>  lib/ring/soring.c | 33 +++++++++++++++------------------
>  1 file changed, 15 insertions(+), 18 deletions(-)
> 
> diff --git a/lib/ring/soring.c b/lib/ring/soring.c
> index 3b90521bdb..4bc2321fb5 100644
> --- a/lib/ring/soring.c
> +++ b/lib/ring/soring.c
> @@ -37,24 +37,24 @@
>   * plus current stage index).
>   * 'release()' extracts old head value from provided ftoken and checks
> that
>   * corresponding 'state[]' contains expected values(mostly for sanity
> - * purposes).
> - * Then it marks this state[] with 'SORING_ST_FINISH' flag to indicate
> - * that given subset of objects was released.
> - * After that, it checks does old head value equals to current tail
> value?
> - * If yes, then it performs  'finalize()' operation, otherwise
> 'release()'
> - * just returns (without spinning on stage tail value).
> - * As updated state[] is shared by all threads, some other thread can
> do
> - * 'finalize()' for given stage.
> - * That allows 'release()' to avoid excessive waits on the tail value.
> + * purposes). Then it marks this state[] with 'SORING_ST_FINISH' flag
> to
> + * indicate that given subset of objects was released.
> + * After that, it calls 'finalize()'.
>   * Main purpose of 'finalize()' operation is to walk through 'state[]'
>   * 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:
> + * Note that updated state[] is shared by all threads, so
> + * '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
> - * guarantee that only one thread will update state[] and stage's tail
> values.
> + * guarantee that only one thread at a time will update state[] and
> + * stage's tail values (sort of critical-section).
> + * When multiple threads trying to do finalize() for the same stage,
> + * simultaneously one thread will win the race and do all the pending
> + * updates, while others will simply return (kind of try-lock
> scenario).
> + * That allows 'release()' to avoid excessive waits on the tail value.
>   */
> 
>  #include "soring.h"
> @@ -442,7 +442,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,12 +479,9 @@ 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,
> -				r->capacity);
> +	/* now, try to do finalize() */
> +	__rte_soring_stage_finalize(&stg->sht, stage, r->state, r->mask,
> +			r->capacity);
>  }
> 
>  /*
> --
> 2.51.0


  reply	other threads:[~2026-04-28 11:54 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     ` [PATCH v3 1/2] ring: make soring to finalize its own stage only Konstantin Ananyev
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 [this message]
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=98CBD80474FA8B44BF855DF32C47DC35F65827@smartserver.smartshare.dk \
    --to=mb@smartsharesystems.com \
    --cc=dev@dpdk.org \
    --cc=konstantin.ananyev@huawei.com \
    --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