Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp1950955pxb; Sat, 27 Feb 2021 05:47:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJzIHy8UCyAyNPEPVZQ0kGXXuilrlpY6VuSKAbGFFPMS3YpyklHpq9+B1OY0W9KFyyGVI6zC X-Received: by 2002:aa7:d1cf:: with SMTP id g15mr8181226edp.270.1614433623939; Sat, 27 Feb 2021 05:47:03 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1614433623; cv=pass; d=google.com; s=arc-20160816; b=nEHmSi7YZY8wR/jk+sTVNtXMcyjBsDof+2/WdYsWfmuNsawTzxqL8gdbrbyKqokBxb 2SMwU3W+QiN8KWfJZVz6/nr+gEMkditIGK97f9aflks5nUc0/ywejyBHgQddxg8m3k7O QdkPwvQCsNBsXNzjM9RvBoLyzEN5NFLlMLaEIrzfXGmZ4JDVOyb0hQOqRIzwguPOKder rU/jZzd7/laI703YU43C41d1gZMB5qLTB/g8H3y33Ni5kWefdOQulTLNlX2APySIZxe0 3K+e1gkmNtv7OY09oLHrTQ05QceyuILzUAmVOXRnlVb6bGhryKpVkv1Xxtrog2XoUqq+ fKFA== ARC-Message-Signature: i=2; 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=qrRxyN7LadI7uDd8DHSxjsKLqYjaf6fPgrPfK6HpFbk=; b=QV4akpHhC7HRK6UYr5TCsSdlYCgFGhjSjHEaFViBK5eGTXQ77tfiN3TAquKLvVzYNu VABDSNG1kpTcAL6AHdOSuKiZUsDjcg1AvKsjJx545ltwqJAQNPswmk9YQvEZUt6uKXqz VJ3j0y52Hw1yRdEHGusV+qKqNc5VNdSWV5o2FU80XyEBJs3TIldI5nxdAY3H9tYWO08P fHT/V8DrW4pIYORZ1HEWi8d65ZXJsk89vS08dPQ+xiMRgcEEJ5oyPtJ/Tzx1A8HRNGxp EmkBs9dj7isT4Zw9cJLDkYVPX5J3xA2x0ri05Bpx5SSiHYRIt2LY719Dyd9mBUFgKYkY fLMw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@chronox.de header.s=strato-dkim-0002 header.b=ceUmtRkg; arc=pass (i=1); 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 a12si5535924ejy.363.2021.02.27.05.46.23; Sat, 27 Feb 2021 05:47:03 -0800 (PST) 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=ceUmtRkg; arc=pass (i=1); 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 S230153AbhB0Npf (ORCPT + 99 others); Sat, 27 Feb 2021 08:45:35 -0500 Received: from mo4-p04-ob.smtp.rzone.de ([85.215.255.120]:9798 "EHLO mo4-p04-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230086AbhB0Npb (ORCPT ); Sat, 27 Feb 2021 08:45:31 -0500 ARC-Seal: i=1; a=rsa-sha256; t=1614433260; cv=none; d=strato.com; s=strato-dkim-0002; b=rsgGfwK95gtKDP84gVWXob04G0Iu0N0aPB+l8P5yPF6UST4739haqG9VMyOcuTOa8W SWotbH3Iu79gLP7J+68D8l7KES4CKtDhZwe0Z3tl8+qbAEzZgph5vYdApxXLhja9XVl/ ut+cd+EVjXaFyWHYtfrUgalS3OktCTRlASYX8Ys8kvbuCa0q7xuffEl3s4S3dARmWgvO 3kMJ9Oi+jmqUG2oFIA3aQiDjODZa24XxCXd5Wi9lZXj180rzQcpokVKw33nEQXTZb4xo W4+6fMSrBjBvOmDMKSDtyfvCK4BgCcJRbgW8/dd3KD5i7dPTLwwUn4advC3D/+i3hPka WyOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1614433260; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=qrRxyN7LadI7uDd8DHSxjsKLqYjaf6fPgrPfK6HpFbk=; b=j8XRCEhNlaXLJpq3IUetpevBMOWLxZZvuudv2FZkclE9QOOJJXw0pemT6wgIrnEylA 3Wf/S/53PvxjRpqbsd90arq3RTWI3LEmSungKF7WCf87gC3vbmPVMULyA7O+Kh/ed/k8 7ILWxW9kMvaU7dwXY566Gj2PSnWnwBtruGAzQLxE/1q9cHot7ElLcfaUmvIKeE5vm+zH yiveTYYmDmPEh8vvx3CGz+R9T87YPtEtKTrz9Uv20Ig+YuJ5a6nywlmJCd2Wu1rMHUa9 9O3pdSBe+RWyOjTX8eezdnCAIpew9LVWvaiSZJkqimSQvLO+lvYIEhMxg71fXm4iuQje U0LQ== ARC-Authentication-Results: i=1; strato.com; dkim=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1614433260; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=qrRxyN7LadI7uDd8DHSxjsKLqYjaf6fPgrPfK6HpFbk=; b=ceUmtRkgb1F5PnSkScd6gw828XFun3tVIDQ4UK0I6AmUfhaLbVxTiGBmXS6rsysG4x tjcjfigSo4ZxWZyXAxVJBH1dgHzxnK66MJ7nmiO2tAOIOZTof+zCYJFTZNkaGisgjEVR HL86HixohE0p7M69Mai3KISDg56cCBiBS6mPgj0YZDLEpFMA+N7sT01CEuSrgJtg8h6X ehE2oK13u17inz6U4ZlkgC/n3pvsKvDger3uPwtU5Ak3WHXdNwFbmWpkktedkrHOa8UO g2joUFmze59+jz+RBQZgDT7hegheAwhngiAsTIkT1aFH3cw9GeBLpn1UaIXZrHraNDdL h1+w== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9xmwdNnzGHXPZIfSc8k+7" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 47.19.0 DYNA|AUTH) with ESMTPSA id 608030x1RDexUDK (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Sat, 27 Feb 2021 14:40:59 +0100 (CET) From: Stephan =?ISO-8859-1?Q?M=FCller?= To: Tso Ted , linux-crypto@vger.kernel.org Cc: Willy Tarreau , Nicolai Stange , LKML , Arnd Bergmann , Greg Kroah-Hartman , "Eric W. Biederman" , "Alexander E. Patrakov" , "Ahmed S. Darwish" , Matthew Garrett , Vito Caputo , Andreas Dilger , Jan Kara , Ray Strode , William Jon McCann , zhangjs , Andy Lutomirski , Florian Weimer , Lennart Poettering , Peter Matthias , Marcelo Henrique Cerri , Neil Horman , Randy Dunlap , Julia Lawall , Dan Carpenter , Andy Lavr , Eric Biggers , "Jason A. Donenfeld" , Petr Tesarik , John Haxby Subject: [PATCH v38 02/13] LRNG - allocate one DRNG instance per NUMA node Date: Sat, 27 Feb 2021 14:35:05 +0100 Message-ID: <4090020.ejJDZkT8p0@positron.chronox.de> In-Reply-To: <3277560.QJadu78ljV@positron.chronox.de> References: <3277560.QJadu78ljV@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: Torsten Duwe 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 | 120 ++++++++++++++++++++++++++++++ 3 files changed, 127 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 d398ac6b5674..1bfb3710c767 100644 =2D-- a/drivers/char/lrng/lrng_internal.h +++ b/drivers/char/lrng/lrng_internal.h @@ -214,8 +214,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..37817771b97a =2D-- /dev/null +++ b/drivers/char/lrng/lrng_numa.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* + * LRNG NUMA support + * + * Copyright (C) 2016 - 2021, 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); + + /* + * Switch the hash used by the per-CPU pool. + * We do not need to lock the new hash as it is not usable yet + * due to **drngs not yet being initialized. + */ + if (lrng_pcpu_switch_hash(node, drng->crypto_cb, drng->hash, + &lrng_cc20_crypto_cb)) + goto err; + + /* + * 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) { + lrng_pcpu_switch_hash(node, &lrng_cc20_crypto_cb, NULL, + drng->crypto_cb); + drng->crypto_cb->lrng_hash_dealloc(drng->hash); + 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.29.2