From patchwork Fri Dec 1 00:03:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 843261 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="pSYdi4UM"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ynvd62QXDz9sNd for ; Fri, 1 Dec 2017 11:03:54 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751850AbdLAADv (ORCPT ); Thu, 30 Nov 2017 19:03:51 -0500 Received: from mail-pg0-f65.google.com ([74.125.83.65]:44475 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751801AbdLAADt (ORCPT ); Thu, 30 Nov 2017 19:03:49 -0500 Received: by mail-pg0-f65.google.com with SMTP id j9so3696409pgc.11 for ; Thu, 30 Nov 2017 16:03:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jnJglxLOPTrqcMlBHrayEQxaN4FaY7J8DKOjcyJsvd8=; b=pSYdi4UMxhcSQ+sWqctndxCvUzBXZQMztyzVQnnXDpOV8smgUSHsn/Sanwslf/eYJd Ir+WwZ7aJI6vbcDAezg4htnaf2OsXPvv2cxtOEo7J5rXTHobJNZ5LR4Spqdm+vFzINVS DcagiL7uP3E3+dGHsQj7uFGtYFluTFAUMXdxfzD3TXN2ydmi2xqWBJOlPwAyB3f9vtMC U4v8+9oRT0wCLS+kohJZyNoVfv/EhpMuoa+Pmko1VvLSRd4UnMpCukGZFFAtxKSK6xWG 5NGVKBSaK12bpfK735kCoSiI7XCCuPabQiDpvdQC43i2vvH2k8P0wf+5vhR4VCm0mf96 /5bw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jnJglxLOPTrqcMlBHrayEQxaN4FaY7J8DKOjcyJsvd8=; b=MqCQTNfWxI7vajesDzn+lVcqrLzY+KlLag6aos0LOblhG9Vew0IurKzwCzM+m9L1uy 0NMnsh79xZpXdYmgnwnftVwa7ArDnw2KImcd3uZGkrMRC+J5PBF23Xk9NTyRg06dRKBq eotdsoHcdU85Q5cy9Fv6AbXSyNTHxWGkZYbocjoJ2tMZpXy64qUKtkYqNcr2/KLFqbob NmrTSJEldapxY0LzcWbC6CvS3TXeG1d0yQtWuLm4Gmolua8WvWCLj2NFY1MgZn+JgfCK SV9x+xMWyy+rOXsi9LCcAG7ZSPrts4rYkkQM7qaCd6xm9+2vCBGPC4GGpNaaB6h7ovCP XU6A== X-Gm-Message-State: AJaThX40XbNaa1PsZDyStcV6EgWqft1ZSs5CU8pgBEbGWMlPCIzdwhk+ 0Rz0qGjZAm9iCmM8rXO4zElEcw== X-Google-Smtp-Source: AGs4zMZI0xt9KFMKRdXf9/kQA3RbyyfOaTuCSgvURalExAPmvsviUpMkkqjQe+//dAGV7Ok2A+g5pQ== X-Received: by 10.98.14.144 with SMTP id 16mr8438539pfo.195.1512086629147; Thu, 30 Nov 2017 16:03:49 -0800 (PST) Received: from localhost.localdomain (c-73-162-13-107.hsd1.ca.comcast.net. [73.162.13.107]) by smtp.gmail.com with ESMTPSA id s66sm10510569pfd.74.2017.11.30.16.03.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 30 Nov 2017 16:03:47 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, rohit@quantonium.net, herbert@gondor.apana.org.au, Tom Herbert Subject: [PATCH net-next 4/5] spinlock: Add library function to allocate spinlock buckets array Date: Thu, 30 Nov 2017 16:03:04 -0800 Message-Id: <20171201000305.2392-5-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171201000305.2392-1-tom@quantonium.net> References: <20171201000305.2392-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add two new library functions: alloc_bucket_spinlocks and free_bucket_spinlocks. These are used to allocate and free an array of spinlocks that are useful as locks for hash buckets. The interface specifies the maximum number of spinlocks in the array as well as a CPU multiplier to derive the number of spinlocks to allocate. The number allocated is rounded up to a power of two to make the array amenable to hash lookup. Signed-off-by: Tom Herbert --- include/linux/spinlock.h | 6 ++++++ lib/Makefile | 2 +- lib/bucket_locks.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 lib/bucket_locks.c diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index a39186194cd6..10fd28b118ee 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -414,4 +414,10 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define atomic_dec_and_lock(atomic, lock) \ __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) +int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, + size_t max_size, unsigned int cpu_mult, + gfp_t gfp); + +void free_bucket_spinlocks(spinlock_t *locks); + #endif /* __LINUX_SPINLOCK_H */ diff --git a/lib/Makefile b/lib/Makefile index d11c48ec8ffd..a6c8529dd9b2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -39,7 +39,7 @@ obj-y += bcd.o div64.o sort.o parser.o debug_locks.o random32.o \ gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ bsearch.o find_bit.o llist.o memweight.o kfifo.o \ percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \ - once.o refcount.o usercopy.o errseq.o + once.o refcount.o usercopy.o errseq.o bucket_locks.o obj-$(CONFIG_STRING_SELFTEST) += test_string.o obj-y += string_helpers.o obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o diff --git a/lib/bucket_locks.c b/lib/bucket_locks.c new file mode 100644 index 000000000000..266a97c5708b --- /dev/null +++ b/lib/bucket_locks.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +/* Allocate an array of spinlocks to be accessed by a hash. Two arguments + * indicate the number of elements to allocate in the array. max_size + * gives the maximum number of elements to allocate. cpu_mult gives + * the number of locks per CPU to allocate. The size is rounded up + * to a power of 2 to be suitable as a hash table. + */ + +int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask, + size_t max_size, unsigned int cpu_mult, gfp_t gfp) +{ + spinlock_t *tlocks = NULL; + unsigned int i, size; +#if defined(CONFIG_PROVE_LOCKING) + unsigned int nr_pcpus = 2; +#else + unsigned int nr_pcpus = num_possible_cpus(); +#endif + + if (cpu_mult) { + nr_pcpus = min_t(unsigned int, nr_pcpus, 64UL); + size = min_t(unsigned int, nr_pcpus * cpu_mult, max_size); + } else { + size = max_size; + } + + if (sizeof(spinlock_t) != 0) { + if (gfpflags_allow_blocking(gfp)) + tlocks = kvmalloc(size * sizeof(spinlock_t), gfp); + else + tlocks = kmalloc_array(size, sizeof(spinlock_t), gfp); + if (!tlocks) + return -ENOMEM; + for (i = 0; i < size; i++) + spin_lock_init(&tlocks[i]); + } + + *locks = tlocks; + *locks_mask = size - 1; + + return 0; +} +EXPORT_SYMBOL(alloc_bucket_spinlocks); + +void free_bucket_spinlocks(spinlock_t *locks) +{ + kvfree(locks); +} +EXPORT_SYMBOL(free_bucket_spinlocks);