From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: "Stephen Hemminger" <stephen@networkplumber.org>,
"Mattias Rönnblom" <mattias.ronnblom@ericsson.com>,
"Bruce Richardson" <bruce.richardson@intel.com>
Subject: [PATCH v2 2/2] random: make rte_rand() thread safe for non-EAL threads
Date: Thu, 7 Sep 2023 08:24:56 -0700 [thread overview]
Message-ID: <20230907152456.20570-3-stephen@networkplumber.org> (raw)
In-Reply-To: <20230907152456.20570-1-stephen@networkplumber.org>
Add missing locking so that if two non-EAL threads call rte_rand()
they will not corrupt the per-thread state.
Fixes: 3f002f069612 ("eal: replace libc-based random generation with LFSR")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/eal/common/rte_random.c | 54 ++++++++++++++++++++++++-------------
1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/lib/eal/common/rte_random.c b/lib/eal/common/rte_random.c
index 812e5b4757b5..02b6b6b97bc0 100644
--- a/lib/eal/common/rte_random.c
+++ b/lib/eal/common/rte_random.c
@@ -11,6 +11,7 @@
#include <rte_branch_prediction.h>
#include <rte_cycles.h>
#include <rte_lcore.h>
+#include <rte_spinlock.h>
#include <rte_random.h>
struct rte_rand_state {
@@ -21,6 +22,9 @@ struct rte_rand_state {
uint64_t z5;
} __rte_cache_aligned;
+/* Used for thread safety for non EAL threads. */
+static rte_spinlock_t rte_rand_lock = RTE_SPINLOCK_INITIALIZER;
+
/* One instance each for every lcore id-equipped thread, and one
* additional instance to be shared by all others threads (i.e., all
* unregistered non-EAL threads).
@@ -124,20 +128,32 @@ struct rte_rand_state *__rte_rand_get_state(void)
idx = rte_lcore_id();
/* last instance reserved for unregistered non-EAL threads */
- if (unlikely(idx == LCORE_ID_ANY))
+ if (unlikely(idx == LCORE_ID_ANY)) {
idx = RTE_MAX_LCORE;
+ rte_spinlock_lock(&rte_rand_lock);
+ }
return &rand_states[idx];
}
+static __rte_always_inline
+void __rte_rand_put_state(struct rte_rand_state *state)
+{
+ if (state == &rand_states[RTE_MAX_LCORE])
+ rte_spinlock_unlock(&rte_rand_lock);
+}
+
uint64_t
rte_rand(void)
{
struct rte_rand_state *state;
+ uint64_t res;
state = __rte_rand_get_state();
+ res = __rte_rand_lfsr258(state);
+ __rte_rand_put_state(state);
- return __rte_rand_lfsr258(state);
+ return res;
}
uint64_t
@@ -159,22 +175,24 @@ rte_rand_max(uint64_t upper_bound)
/* Handle power-of-2 upper_bound as a special case, since it
* has no bias issues.
*/
- if (unlikely(ones == 1))
- return __rte_rand_lfsr258(state) & (upper_bound - 1);
-
- /* The approach to avoiding bias is to create a mask that
- * stretches beyond the request value range, and up to the
- * next power-of-2. In case the masked generated random value
- * is equal to or greater than the upper bound, just discard
- * the value and generate a new one.
- */
-
- leading_zeros = rte_clz64(upper_bound);
- mask >>= leading_zeros;
-
- do {
- res = __rte_rand_lfsr258(state) & mask;
- } while (unlikely(res >= upper_bound));
+ if (unlikely(ones == 1)) {
+ res = __rte_rand_lfsr258(state) & (upper_bound - 1);
+ } else {
+ /* The approach to avoiding bias is to create a mask that
+ * stretches beyond the request value range, and up to the
+ * next power-of-2. In case the masked generated random value
+ * is equal to or greater than the upper bound, just discard
+ * the value and generate a new one.
+ */
+
+ leading_zeros = rte_clz64(upper_bound);
+ mask >>= leading_zeros;
+
+ do {
+ res = __rte_rand_lfsr258(state) & mask;
+ } while (unlikely(res >= upper_bound));
+ }
+ __rte_rand_put_state(state);
return res;
}
--
2.39.2
next prev parent reply other threads:[~2023-09-07 15:25 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-06 15:53 [PATCH] random: initialize the random state for non-eal lcores Stephen Hemminger
2023-09-06 16:25 ` Morten Brørup
2023-09-06 16:28 ` Stephen Hemminger
2023-09-07 15:24 ` [PATCH v2 0/2] fixes to rte_random for non-EAL threads Stephen Hemminger
2023-09-07 15:24 ` [PATCH v2 1/2] random: initialize the random state " Stephen Hemminger
2023-10-02 9:00 ` Morten Brørup
2023-10-02 12:27 ` Mattias Rönnblom
2023-10-02 16:07 ` Stephen Hemminger
2023-10-04 8:45 ` David Marchand
2023-09-07 15:24 ` Stephen Hemminger [this message]
2023-09-07 15:47 ` [PATCH v2 2/2] random: make rte_rand() thread safe " Stephen Hemminger
2023-09-07 16:10 ` David Marchand
2023-09-08 20:48 ` Mattias Rönnblom
2023-09-08 20:56 ` Stephen Hemminger
2023-09-09 7:00 ` Mattias Rönnblom
2023-10-02 16:10 ` Stephen Hemminger
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=20230907152456.20570-3-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=mattias.ronnblom@ericsson.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.