Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp2287979pxb; Fri, 17 Sep 2021 06:34:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzQ0K8+x68P6opq1ah7gU4AXLJZdIhylrYzHbTjbEMtdW5qjrMYkEGiLgsfhUm5GvFaaMX3 X-Received: by 2002:a17:906:3693:: with SMTP id a19mr12536130ejc.237.1631885698363; Fri, 17 Sep 2021 06:34:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631885698; cv=none; d=google.com; s=arc-20160816; b=url4sEUJ2u4aKyxiWdpszOc9tFhwNupCPCV+pXNpVCuvlsJyGcZEDXPxwWgy2cq3x7 dvXi1n3v/igw9YV1i9t1avepobzhoDj9AJqmnDmCUhUp3XPYiHqJb6C8EDsUDLhNcqJO pqkutxNItDuX8xxeN1XjfXc3zVA+VrFoPhhJZ6s9cK6sUzN8VzLwCPxXa/WPbNy4h7Dz Dylq4b77Xahv39NiTLEhYqmEASwSP7NzsPnjFp082ehbcb7sbNuBgiZeahCszTLfU/yh tIsqB3q799hGloeLpjnEACNQHs+Pd8XRMFWnoUj/lsrfWS+89lBLpAW0ibCMJ1QOKxKH PmTA== 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=YYVyCa1AKBYWEXJ5Aa0jWO5d0uV4daDcsZ2R9K5cQDM=; b=mf4ExwS9oq1qGHOyZYsQ8b9YbSwsI3YPgBIUT+M8fRXO0YEDbXYAm93qQTNHLF6oQK 2dLzyrCPmRCiQIAaCfFxY2cxUh5RK7OJw1h3NdGHPMzgozC61Csj30zOh3HntJ9l9BKE O2OuPhF+SLDyc5EVTbUMHzIh6/kSkS/O4U2r8O8saTjb8XSWJQ36GtoOrac7EHahq9Nd mh7L9U4VUBT+EECiPlTQwwGkLsI9JaiOFTigSjwMwo6J9nhNP0TwyGEIbjd1gat4J17/ KhkH2YJ5R4VX71q0z/uWosinZbnaqNpoyQ166dOSG8EIbjfw6EdbVy4QV35Fyddl91KN mSRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chronox.de header.s=strato-dkim-0002 header.b=OSehhtza; 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 l13si6977621edv.249.2021.09.17.06.34.27; Fri, 17 Sep 2021 06:34:58 -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=OSehhtza; 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 S245615AbhIQJj4 (ORCPT + 99 others); Fri, 17 Sep 2021 05:39:56 -0400 Received: from mo4-p04-ob.smtp.rzone.de ([85.215.255.121]:34298 "EHLO mo4-p04-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241403AbhIQJjw (ORCPT ); Fri, 17 Sep 2021 05:39:52 -0400 X-Greylist: delayed 302 seconds by postgrey-1.27 at vger.kernel.org; Fri, 17 Sep 2021 05:39:52 EDT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1631871144; 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=YYVyCa1AKBYWEXJ5Aa0jWO5d0uV4daDcsZ2R9K5cQDM=; b=OSehhtzafoaFw/3/MFNpWPqKeK5Xg6Su5SB7NuTwtX2knT3E3QtX9JKChHszLUH4Us J+LT80OxDX88Rp6H9MjacZyIMJq1Wda7efRsHsGJ1nk4dz6dtO+XzBMT6VD0MoHXfSRV Bo6I8X02GT9aBiM/uR91nGNGbFQOGbmAASockj1MrBvQiDDlNFhpfoXmTvnpg6AUH/+m A9v2YoW9UTM3zmKa0GlhdkTUO3zTS3bXEioxEsrDw52s3rNN5WomuricHNZtY5JdT549 Ez5mxXr+QPiz60bjZklxQMZ1+CwWHRlerrIy9W1VHV75JuOO6TlT1VjgPoUlH4PpqWcE VzYw== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9xmwdNnzGHXvSOeicf6o=" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 47.33.3 DYNA|AUTH) with ESMTPSA id f080d4x8H9WNcpf (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Fri, 17 Sep 2021 11:32:23 +0200 (CEST) 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 , Alexander Lobakin Subject: [PATCH v42 02/13] LRNG - allocate one DRNG instance per NUMA node Date: Thu, 16 Sep 2021 12:12:08 +0200 Message-ID: <8416707.0CM7ZkIBX3@positron.chronox.de> In-Reply-To: <2294055.9jK4hKOXjS@positron.chronox.de> References: <2294055.9jK4hKOXjS@positron.chronox.de> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" 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: Alexander Lobakin Tested-by: Alexander Lobakin Reviewed-by: Marcelo Henrique Cerri Reviewed-by: Roman Drahtmueller Tested-by: Marcelo Henrique Cerri Tested-by: Neil Horman Signed-off-by: Stephan Mueller --- drivers/char/lrng/Makefile | 2 + drivers/char/lrng/lrng_numa.c | 122 ++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 drivers/char/lrng/lrng_numa.c diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile index c26f932628d7..80b152059598 100644 --- a/drivers/char/lrng/Makefile +++ b/drivers/char/lrng/Makefile @@ -7,3 +7,5 @@ obj-y += lrng_es_mgr.o lrng_aux.o \ lrng_es_irq.o lrng_es_archrandom.o \ lrng_drng.o lrng_chacha20.o \ lrng_interfaces.o lrng_es_aux.o + +obj-$(CONFIG_NUMA) += lrng_numa.o diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c new file mode 100644 index 000000000000..fbfb40a5fb8d --- /dev/null +++ b/drivers/char/lrng/lrng_numa.c @@ -0,0 +1,122 @@ +// 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 = 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 = lrng_drng_init_instance(); + u32 node; + bool init_drng_used = false; + + mutex_lock(&lrng_crypto_cb_update); + + /* per-NUMA-node DRNGs are already present */ + if (lrng_drng) + goto unlock; + + drngs = 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] = lrng_drng_init; + init_drng_used = true; + continue; + } + + drng = kmalloc_node(sizeof(struct lrng_drng), + GFP_KERNEL|__GFP_NOFAIL, node); + memset(drng, 0, sizeof(lrng_drng)); + + drng->crypto_cb = lrng_drng_init->crypto_cb; + drng->drng = drng->crypto_cb->lrng_drng_alloc( + LRNG_DRNG_SECURITY_STRENGTH_BYTES); + if (IS_ERR(drng->drng)) { + kfree(drng); + goto err; + } + + drng->hash = 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] = 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)) { + lrng_pool_all_numa_nodes_seeded(false); + goto unlock; + } + +err: + for_each_online_node(node) { + struct lrng_drng *drng = drngs[node]; + + if (drng == 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); +} -- 2.31.1