From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id A2DE942537; Thu, 7 Sep 2023 17:25:23 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D8983402E5; Thu, 7 Sep 2023 17:25:13 +0200 (CEST) Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) by mails.dpdk.org (Postfix) with ESMTP id A4E24402C6 for ; Thu, 7 Sep 2023 17:25:10 +0200 (CEST) Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-1c328b53aeaso9145595ad.2 for ; Thu, 07 Sep 2023 08:25:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1694100309; x=1694705109; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TY+OZQDjCfeely1UFsBLMdsvhdMtisbaGN6NwHNR1aU=; b=Srl2nkr4fVUsptc+RJ8WzaJX8s226GGgv07iYEheeZGi5khBJD0bMlQutKmYPAGWWm bLXvkdL+5hg7w7dz4f2U8Vu9dsx8azQdiJGs1Pgr2WPlWaC0MekAWqCVsNUNWGTJr6b1 mrEZQcbXj74RDhfs9C9ZH0dbSY2DC4d4CIh5sJ83EL45Ph/CRvu7HTTimM4pm6Q5vqaM V+0paKygsxSxb/P3Oi+FecSxnjrPt/KshmEdKLfj92dPSy5FOPDvhYy2TRnGqq+h6CzG e5Sggs9JeEkIFH+ljiEA9JWv5+Xwu56fpElU988If9UnCUIwLXeGFEvc76UTRB3QsNdE U01g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1694100309; x=1694705109; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TY+OZQDjCfeely1UFsBLMdsvhdMtisbaGN6NwHNR1aU=; b=k8crTZvM71eoiEUOVIemCfPe1LJvFzGbhgwH9LMwXRgfixHKCj6ldMn6BpWkrSZ4f8 MS4VY55fkyMOl49M+97g3FEvrlzHu2xWmzsULFzNKmfrHjnuK9j/dxqff8BM4gfsd7iv ZjGMZoS8tvDu3MAKYB4h+bp5gcNbL4pgFmuMdAAmj6/IIifLOtAp3ZCNocpK3c61oAPi oE7z4ZBONdNEOpw3wTfxU1BJ375xewzlHU+XL8H5gLHa+4Arbj2J6CLdazuZWVlXifXv 61r+JkT7fPJqo4935hoQcuz/Q/KlvYHjNjKXS7ZBtJm1dTSnL911ZgIOn3GrVcRjSAZU y8UQ== X-Gm-Message-State: AOJu0YwE4khfCwdF49FX3DOxbuFgXJcj/6jlZb0DGUWpYSNwL6FJnJM2 dqlZPzgnXJpOeiHBjQtFKuEtRIhH+zrDuro9Huk= X-Google-Smtp-Source: AGHT+IE0n0UsPe4yloLnIRX9jUP+hC5ITZlOWZDHvp6rH1evKQfGZdM6/IqK1NRymHKFE3bskzz1AQ== X-Received: by 2002:a17:902:b485:b0:1bc:9651:57c6 with SMTP id y5-20020a170902b48500b001bc965157c6mr18525153plr.57.1694100309507; Thu, 07 Sep 2023 08:25:09 -0700 (PDT) Received: from hermes.local (204-195-112-131.wavecable.com. [204.195.112.131]) by smtp.gmail.com with ESMTPSA id e2-20020a170902b78200b001aaf2e8b1eesm12864400pls.248.2023.09.07.08.25.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Sep 2023 08:25:09 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger , =?UTF-8?q?Mattias=20R=C3=B6nnblom?= , Bruce Richardson Subject: [PATCH v2 2/2] random: make rte_rand() thread safe for non-EAL threads Date: Thu, 7 Sep 2023 08:24:56 -0700 Message-Id: <20230907152456.20570-3-stephen@networkplumber.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230907152456.20570-1-stephen@networkplumber.org> References: <20230906155302.82749-1-stephen@networkplumber.org> <20230907152456.20570-1-stephen@networkplumber.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.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 --- 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 #include #include +#include #include 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