Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1077252pxk; Fri, 18 Sep 2020 03:14:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxMNBomYEZ7fT8sPK0cCctud8DAeyUsuM6FyzJckiorAYniyK6d4wPpm52DXzRxA5algXz+ X-Received: by 2002:a17:906:a256:: with SMTP id bi22mr34614316ejb.375.1600424071390; Fri, 18 Sep 2020 03:14:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600424071; cv=none; d=google.com; s=arc-20160816; b=TERiZTAlWjJPfAOm777skuzTBPLkRTnCydZRv0d0Dejm43+PycW4oNF9da3xeJgLdK QiZrx3lw4JHBJW0LkM2zGwIsJuuWp51Lh0xtlJX2vVqsHpXjHOBCqncvW4ZpNZWi2UwH b337c0eMTc3aRG9uCgK0SQHqBmRSqMutJ/QHgIOe5YZlWbmXgHhMkHehP3ey7zBa5d7/ bDXLcp5d8k4zyx18NuAHnjfm93QWxdEZZvupoN/kONAEl1Y0RRLH6mLzVhaoNGWogSqL /ntk+z5B5oUZtELi1uJqa91hYDiRAhI+kmkAbznNkAq7xYMhiCTMfS+CvS0zT80Hc/gb m3Qg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=VFX/4H+Fp6WIcpDWL6qyIcpPl9XvdY3vSgLNLkOYZI4=; b=JaMvjH3MP7cxPV3wrF987BEmMePEpm7feLAiPqeRuXxDv0nisjVhCYZ95tVEsvtfOJ f9tzfTO8EudqlUqbHT/AsWKnKQRaAJ/+0+4+2tW2juJpVQKjZLTnO/654Dj7HvBuiAJB QvVQwHnYHJy58xQc+Uyr99Px1JKYMtXCP9lUCMAR3wZL1Aa7g+RBx7JFXdkpM4lAhHvn AXnPxyxS88RGhDsPiwmhF/1k6iEJ8bFLZzyg5AqkqU2XlhL+BSvXwRfsl9vuDwEARqJQ Aw3TFYBkpxMXth3QdFUsJxl1Jb4b/ZitqkD59DQHRZPK226DbXu79YYMjyrhCbZMw5is ATOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chronox.de header.s=strato-dkim-0002 header.b=hBe5y1xP; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id cy18si1786068edb.148.2020.09.18.03.14.07; Fri, 18 Sep 2020 03:14:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chronox.de header.s=strato-dkim-0002 header.b=hBe5y1xP; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726765AbgIRKMw (ORCPT + 99 others); Fri, 18 Sep 2020 06:12:52 -0400 Received: from mo4-p04-ob.smtp.rzone.de ([85.215.255.120]:13963 "EHLO mo4-p04-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726710AbgIRKMb (ORCPT ); Fri, 18 Sep 2020 06:12:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1600423946; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=VFX/4H+Fp6WIcpDWL6qyIcpPl9XvdY3vSgLNLkOYZI4=; b=hBe5y1xPiS4LfavoIFPLwer8vogtdnvK/vpcFTX6TJCpZqAZ7hvR3WZhx8rf6Wx+8B MAjASGcQcdUvVGKITLFX68YTan/mXaOHE+jyAeqYR9G829Y5u+vNCU9MvBCUM4i8n9Nn I5QVEr6R8Je1wPdqn9Wfq09HRcX+iwuXCJLIFYq92oaGf7yugf0OGYt6EK5fpmVtnIlt qRhaxw6YSQUAKB1bIh3zvgNU/KdLuG5d5xJP8YCkCyYLvgNTLBNw+fbSDS95JcL7lx34 U6+0DVmfY/te+AvyYqXQBjACR+xN/CqB0P3BDiJFOZNUa2i3hHtp/Z1Dfpb1VHCl0+T7 RZGA== X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9xmwdNnzHHXDaJPScXyVH" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 46.10.7 DYNA|AUTH) with ESMTPSA id 002e9aw8IA0K2TH (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Fri, 18 Sep 2020 12:00:20 +0200 (CEST) From: Stephan =?ISO-8859-1?Q?M=FCller?= To: Arnd Bergmann Cc: Greg Kroah-Hartman , linux-crypto@vger.kernel.org, LKML , linux-api@vger.kernel.org, "Eric W. Biederman" , "Alexander E. Patrakov" , "Ahmed S. Darwish" , "Theodore Y. Ts'o" , Willy Tarreau , Matthew Garrett , Vito Caputo , Andreas Dilger , Jan Kara , Ray Strode , William Jon McCann , zhangjs , Andy Lutomirski , Florian Weimer , Lennart Poettering , Nicolai Stange , "Peter, Matthias" , Marcelo Henrique Cerri , Roman Drahtmueller , Neil Horman , Randy Dunlap , Julia Lawall , Dan Carpenter , Andy Lavr , ebiggers@kernel.org Subject: [PATCH v35 02/13] LRNG - allocate one DRNG instance per NUMA node Date: Fri, 18 Sep 2020 11:48:39 +0200 Message-ID: <4591352.GXAFRqVoOG@positron.chronox.de> In-Reply-To: <5667034.lOV4Wx5bFT@positron.chronox.de> References: <2544450.mvXUDI8C0e@positron.chronox.de> <5532247.MhkbZ0Pkbq@positron.chronox.de> <5667034.lOV4Wx5bFT@positron.chronox.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org In order to improve NUMA-locality when serving getrandom(2) requests, allocate one DRNG instance per node. The DRNG instance that is present right from the start of the kernel is reused as the first per-NUMA-node DRNG. For all remaining online NUMA nodes a new DRNG instance is allocated. During boot time, the multiple DRNG instances are seeded sequentially. With this, the first DRNG instance (referenced as the initial DRNG in the code) is completely seeded with 256 bits of entropy before the next DRNG instance is completely seeded. When random numbers are requested, the NUMA-node-local DRNG is checked whether it has been already fully seeded. If this is not the case, the initial DRNG is used to serve the request. CC: "Eric W. Biederman" CC: "Alexander E. Patrakov" CC: "Ahmed S. Darwish" CC: "Theodore Y. Ts'o" CC: Willy Tarreau CC: Matthew Garrett CC: Vito Caputo CC: Andreas Dilger CC: Jan Kara CC: Ray Strode CC: William Jon McCann CC: zhangjs CC: Andy Lutomirski CC: Florian Weimer CC: Lennart Poettering CC: Nicolai Stange CC: Eric Biggers Reviewed-by: Marcelo Henrique Cerri Reviewed-by: Roman Drahtmueller Tested-by: Roman Drahtm=FCller Tested-by: Marcelo Henrique Cerri Tested-by: Neil Horman Signed-off-by: Stephan Mueller =2D-- drivers/char/lrng/Makefile | 2 + drivers/char/lrng/lrng_internal.h | 5 ++ drivers/char/lrng/lrng_numa.c | 108 ++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 drivers/char/lrng/lrng_numa.c diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile index e72e01c15bb9..29724c65287d 100644 =2D-- a/drivers/char/lrng/Makefile +++ b/drivers/char/lrng/Makefile @@ -7,3 +7,5 @@ obj-y +=3D lrng_pool.o lrng_aux.o \ lrng_sw_noise.o lrng_archrandom.o \ lrng_drng.o lrng_chacha20.o \ lrng_interfaces.o + +obj-$(CONFIG_NUMA) +=3D lrng_numa.o diff --git a/drivers/char/lrng/lrng_internal.h b/drivers/char/lrng/lrng_int= ernal.h index bf0b32eb9113..c405cbf379d6 100644 =2D-- a/drivers/char/lrng/lrng_internal.h +++ b/drivers/char/lrng/lrng_internal.h @@ -219,8 +219,13 @@ int lrng_drng_get_sleep(u8 *outbuf, u32 outbuflen); void lrng_drng_force_reseed(void); void lrng_drng_seed_work(struct work_struct *dummy); =20 +#ifdef CONFIG_NUMA +struct lrng_drng **lrng_drng_instances(void); +void lrng_drngs_numa_alloc(void); +#else /* CONFIG_NUMA */ static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; } static inline void lrng_drngs_numa_alloc(void) { return; } +#endif /* CONFIG_NUMA */ =20 /************************** Entropy pool management **********************= *****/ =20 diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c new file mode 100644 index 000000000000..7f1f0dade1b6 =2D-- /dev/null +++ b/drivers/char/lrng/lrng_numa.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* + * LRNG NUMA support + * + * Copyright (C) 2016 - 2020, Stephan Mueller + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include + +#include "lrng_internal.h" + +static struct lrng_drng **lrng_drng __read_mostly =3D NULL; + +struct lrng_drng **lrng_drng_instances(void) +{ + return smp_load_acquire(&lrng_drng); +} + +/* Allocate the data structures for the per-NUMA node DRNGs */ +static void _lrng_drngs_numa_alloc(struct work_struct *work) +{ + struct lrng_drng **drngs; + struct lrng_drng *lrng_drng_init =3D lrng_drng_init_instance(); + u32 node; + bool init_drng_used =3D false; + + mutex_lock(&lrng_crypto_cb_update); + + /* per-NUMA-node DRNGs are already present */ + if (lrng_drng) + goto unlock; + + drngs =3D kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL); + for_each_online_node(node) { + struct lrng_drng *drng; + + if (!init_drng_used) { + drngs[node] =3D lrng_drng_init; + init_drng_used =3D true; + continue; + } + + drng =3D kmalloc_node(sizeof(struct lrng_drng), + GFP_KERNEL|__GFP_NOFAIL, node); + memset(drng, 0, sizeof(lrng_drng)); + + drng->crypto_cb =3D lrng_drng_init->crypto_cb; + drng->drng =3D drng->crypto_cb->lrng_drng_alloc( + LRNG_DRNG_SECURITY_STRENGTH_BYTES); + if (IS_ERR(drng->drng)) { + kfree(drng); + goto err; + } + + drng->hash =3D drng->crypto_cb->lrng_hash_alloc(); + if (IS_ERR(drng->hash)) { + drng->crypto_cb->lrng_drng_dealloc(drng->drng); + kfree(drng); + goto err; + } + + mutex_init(&drng->lock); + spin_lock_init(&drng->spin_lock); + rwlock_init(&drng->hash_lock); + + /* + * No reseeding of NUMA DRNGs from previous DRNGs as this + * would complicate the code. Let it simply reseed. + */ + lrng_drng_reset(drng); + drngs[node] =3D drng; + + lrng_pool_inc_numa_node(); + pr_info("DRNG and entropy pool read hash for NUMA node %d allocated\n", + node); + } + + /* counterpart to smp_load_acquire in lrng_drng_instances */ + if (!cmpxchg_release(&lrng_drng, NULL, drngs)) + goto unlock; + +err: + for_each_online_node(node) { + struct lrng_drng *drng =3D drngs[node]; + + if (drng =3D=3D lrng_drng_init) + continue; + + if (drng) { + drng->crypto_cb->lrng_drng_dealloc(drng->drng); + kfree(drng); + } + } + kfree(drngs); + +unlock: + mutex_unlock(&lrng_crypto_cb_update); +} + +static DECLARE_WORK(lrng_drngs_numa_alloc_work, _lrng_drngs_numa_alloc); + +void lrng_drngs_numa_alloc(void) +{ + schedule_work(&lrng_drngs_numa_alloc_work); +} =2D-=20 2.26.2