From patchwork Mon Dec 4 18:31:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 844367 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="U0FrIzFN"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yrD4n6xdVz9ryk for ; Tue, 5 Dec 2017 05:32:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752519AbdLDScX (ORCPT ); Mon, 4 Dec 2017 13:32:23 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:43722 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752488AbdLDScQ (ORCPT ); Mon, 4 Dec 2017 13:32:16 -0500 Received: by mail-pg0-f66.google.com with SMTP id b18so8781907pgv.10 for ; Mon, 04 Dec 2017 10:32:16 -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=U0FrIzFNSG4Lerft6A6f/sKXCzOSQp+Mcb2j0IqoKGCJi5OnGQk+xENh0yOrVT4zyk S2SW5DxhDYPlE1zr5xe0RBMK2bVdbHeyLEhce6TeZTst7um3+2cToVrEi0fqnuu9gOw6 rp91Ll8x3xsZVor4DQA0OmEUhffF3N0ZYTryFi9OyY8p+HMPaQ2FqBf/Rb/EFtxzgYC7 57wpFLNVIJmxkcpzyBCVZTs6/YmhHyZjffdp2KkKfh6Ultxj7TDhQ3spMcnlgmS+ZfBB m8sM14VmOo1DBM7zhK3nJmaJVXmjMmS8Mjz4E5UuzdK38Y6iiqMIODADyoeuqjND6uTC j5cQ== 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=TDeUoXIQkD26gp3CxUCGUfXhS+lx3NZyOsQgth1Hkj7AecyFkTUBC7VBdellkf20k7 SbJpXgogIc8tshBLKABVFbBlV2EQ2osN+uCZ7cY2dwxYhopYF0tQhYoZWmH0LGFQKO7X bF4OdsqfAcX5U2xo5vtb6+PcYWnaFmLsMdTjIH3xlUhZ6AsEgaVsQMx3Ad5kVZizKM0M vm2l6MMayKfots/Z9GE/7QQXg7iGODOTtigzwbG9WDxoZNvycsRgCSB51A+JTDYfo+ul AtJj4fhBeM3YlH7/5k/08873FWqChmcoVHTDCD8h9eAGFCwufLu8uRBjdPH44hblO4NN +U9g== X-Gm-Message-State: AJaThX6EHKL/QKvN5y8qIt31EkZsGu5JxYZe2yG9NFxqgKzl/5QKlKp1 kwzLxLcOIXgENcYjpM8UR7bpTg== X-Google-Smtp-Source: AGs4zMZiswpAvTG+4KFWBzYBibcLTnzaGIxq2gbJmWk3ywYD5/1eaedvT1XiUSflUBuoH+dKgsPlKw== X-Received: by 10.99.64.68 with SMTP id n65mr14762896pga.312.1512412335933; Mon, 04 Dec 2017 10:32:15 -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 z2sm3558962pgu.17.2017.12.04.10.32.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Dec 2017 10:32:15 -0800 (PST) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, herbert@gondor.apana.org.au, rohit@quantonium.net, Tom Herbert Subject: [PATCH v2 net-next 4/5] spinlock: Add library function to allocate spinlock buckets array Date: Mon, 4 Dec 2017 10:31:44 -0800 Message-Id: <20171204183145.3277-5-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171204183145.3277-1-tom@quantonium.net> References: <20171204183145.3277-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);