From patchwork Sat Nov 18 15:50:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13460138 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UZjC7tBN" Received: from mail-yw1-x1135.google.com (mail-yw1-x1135.google.com [IPv6:2607:f8b0:4864:20::1135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B479D5D; Sat, 18 Nov 2023 07:51:11 -0800 (PST) Received: by mail-yw1-x1135.google.com with SMTP id 00721157ae682-5a7b3d33663so33593727b3.3; Sat, 18 Nov 2023 07:51:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700322670; x=1700927470; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FtFgcsJzlik9FHkciB+wVhA9q1gRoy67qNZRN3dQ8lw=; b=UZjC7tBNqvQ3LIO2JEbZpu4Q0crbsl24RDzQZGegNn0OPUZtZkCs/29OiPNhN9M6hV LGQfkl6+A4mr1ghE7QlKE5WVMvjzh97Noc6mKXMXAtrCrDeH6mN8x1jMHu+o2H8nuIOU fP7UySeohS+rHUNG1bsyWAblwvz4bsNDaC1OXXy9FuUbcxUUA6Ux7wJZWe9MAV4/jedp xZCqNXd1CqM3KVqezWw7KzonotD6xlPCv49WV9PmhnPNew3jHAaJxyGyXSjqFMUF2Ens /EwmD11tsZ4einav7TJeHBAfpDkqAct0wMmE2O8TT/eSczS7RddMqXulsP/Y25Bxw7/N MgAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700322670; x=1700927470; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FtFgcsJzlik9FHkciB+wVhA9q1gRoy67qNZRN3dQ8lw=; b=AYNyWKbpsOhVqyVRgfSGLZYBkgi4+qonyBdzpiqA6V+xDCQAAcpuvE4idFytExulVA dAcFCkKwu1k+3ekNbdAMhfjq/3PVJj8XXOLc11wHTLH4iRJFv4I+WzHGgWo4m9nZ3cah pHM3Q5mh59Mt2ttza1dyvw4V/eNzXs8h/MsIVbsvRrad0aUg71vehFBWgzmDzF7rKbc+ uqBr6f02n0jKguWhofpONka0WbDNJ22aPceP8LK9hkfkx3QIO77Xk78fGjKj39SqOjyY vRMUQhWQUXG7aUZrTbmuoX/nypF0QGVf9UYj/LFirtMTIPhaBNQh6QCxylFlcYvJ/a6J CReQ== X-Gm-Message-State: AOJu0Yysly0aPPgP+HrBgWiIDtZ6UuxLtRUlY5It1T8pzJQGL/yWfVFo XsgfyxzHEA3WHK9NIwZhDeZi63ihhZcdE+4D X-Google-Smtp-Source: AGHT+IHUmWgte7gPRldUGsddVvZ0jBBaJ21NuiOWnYAoUu1ELu9emBQdDvxqbio5n2yoz/YHpW+BMw== X-Received: by 2002:a0d:cbd7:0:b0:5a7:ba17:15ac with SMTP id n206-20020a0dcbd7000000b005a7ba1715acmr3133986ywd.41.1700322669620; Sat, 18 Nov 2023 07:51:09 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:48a9:bd4c:868d:dc97]) by smtp.gmail.com with ESMTPSA id p127-20020a0dcd85000000b005a7bbd713ddsm1151825ywd.108.2023.11.18.07.51.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Nov 2023 07:51:08 -0800 (PST) From: Yury Norov To: linux-kernel@vger.kernel.org, "David S. Miller" , "H. Peter Anvin" , "James E.J. Bottomley" , "K. Y. Srinivasan" , "Md. Haris Iqbal" , Akinobu Mita , Andrew Morton , Bjorn Andersson , Borislav Petkov , Chaitanya Kulkarni , Christian Brauner , Damien Le Moal , Dave Hansen , David Disseldorp , Edward Cree , Eric Dumazet , Fenghua Yu , Geert Uytterhoeven , Greg Kroah-Hartman , Gregory Greenman , Hans Verkuil , Hans de Goede , Hugh Dickins , Ingo Molnar , Jakub Kicinski , Jaroslav Kysela , Jason Gunthorpe , Jens Axboe , Jiri Pirko , Jiri Slaby , Kalle Valo , Karsten Graul , Karsten Keil , Kees Cook , Leon Romanovsky , Mark Rutland , Martin Habets , Mauro Carvalho Chehab , Michael Ellerman , Michal Simek , Nicholas Piggin , Oliver Neukum , Paolo Abeni , Paolo Bonzini , Peter Zijlstra , Ping-Ke Shih , Rich Felker , Rob Herring , Robin Murphy , Sathya Prakash Veerichetty , Sean Christopherson , Shuai Xue , Stanislaw Gruszka , Steven Rostedt , Thomas Bogendoerfer , Thomas Gleixner , Valentin Schneider , Vitaly Kuznetsov , Wenjia Zhang , Will Deacon , Yoshinori Sato , GR-QLogic-Storage-Upstream@marvell.com, alsa-devel@alsa-project.org, ath10k@lists.infradead.org, dmaengine@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-block@vger.kernel.org, linux-bluetooth@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linux-media@vger.kernel.org, linux-mips@vger.kernel.org, linux-net-drivers@amd.com, linux-pci@vger.kernel.org, linux-rdma@vger.kernel.org, linux-s390@vger.kernel.org, linux-scsi@vger.kernel.org, linux-serial@vger.kernel.org, linux-sh@vger.kernel.org, linux-sound@vger.kernel.org, linux-usb@vger.kernel.org, linux-wireless@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, mpi3mr-linuxdrv.pdl@broadcom.com, netdev@vger.kernel.org, sparclinux@vger.kernel.org, x86@kernel.org Cc: Yury Norov , Jan Kara , Mirsad Todorovac , Matthew Wilcox , Rasmus Villemoes , Andy Shevchenko , Maxim Kuvyrkov , Alexey Klimov Subject: [PATCH 01/34] lib/find: add atomic find_bit() primitives Date: Sat, 18 Nov 2023 07:50:32 -0800 Message-Id: <20231118155105.25678-2-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231118155105.25678-1-yury.norov@gmail.com> References: <20231118155105.25678-1-yury.norov@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add helpers around test_and_{set,clear}_bit() that allow to search for clear or set bits and flip them atomically. The target patterns may look like this: for (idx = 0; idx < nbits; idx++) if (test_and_clear_bit(idx, bitmap)) do_something(idx); Or like this: do { bit = find_first_bit(bitmap, nbits); if (bit >= nbits) return nbits; } while (!test_and_clear_bit(bit, bitmap)); return bit; In both cases, the opencoded loop may be converted to a single function or iterator call. Correspondingly: for_each_test_and_clear_bit(idx, bitmap, nbits) do_something(idx); Or: return find_and_clear_bit(bitmap, nbits); Obviously, the less routine code people have write themself, the less probability to make a mistake. Those are not only handy helpers but also resolve a non-trivial issue of using non-atomic find_bit() together with atomic test_and_{set,clear)_bit(). The trick is that find_bit() implies that the bitmap is a regular non-volatile piece of memory, and compiler is allowed to use such optimization techniques like re-fetching memory instead of caching it. For example, find_first_bit() is implemented like this: for (idx = 0; idx * BITS_PER_LONG < sz; idx++) { val = addr[idx]; if (val) { sz = min(idx * BITS_PER_LONG + __ffs(val), sz); break; } } On register-memory architectures, like x86, compiler may decide to access memory twice - first time to compare against 0, and second time to fetch its value to pass it to __ffs(). When running find_first_bit() on volatile memory, the memory may get changed in-between, and for instance, it may lead to passing 0 to __ffs(), which is undefined. This is a potentially dangerous call. find_and_clear_bit() as a wrapper around test_and_clear_bit() naturally treats underlying bitmap as a volatile memory and prevents compiler from such optimizations. Now that KCSAN is catching exactly this type of situations and warns on undercover memory modifications. We can use it to reveal improper usage of find_bit(), and convert it to atomic find_and_*_bit() as appropriate. The 1st patch of the series adds the following atomic primitives: find_and_set_bit(addr, nbits); find_and_set_next_bit(addr, nbits, start); ... Here find_and_{set,clear} part refers to the corresponding test_and_{set,clear}_bit function, and suffixes like _wrap or _lock derive semantics from corresponding find() or test() functions. For brevity, the naming omits the fact that we search for zero bit in find_and_set, and correspondingly, search for set bit in find_and_clear functions. The patch also adds iterators with atomic semantics, like for_each_test_and_set_bit(). Here, the naming rule is to simply prefix corresponding atomic operation with 'for_each'. All users of find_bit() API, where heavy concurrency is expected, are encouraged to switch to atomic find_and_bit() as appropriate. Signed-off-by: Yury Norov --- include/linux/find.h | 289 +++++++++++++++++++++++++++++++++++++++++++ lib/find_bit.c | 85 +++++++++++++ 2 files changed, 374 insertions(+) diff --git a/include/linux/find.h b/include/linux/find.h index 5e4f39ef2e72..e8567f336f42 100644 --- a/include/linux/find.h +++ b/include/linux/find.h @@ -32,6 +32,16 @@ extern unsigned long _find_first_and_bit(const unsigned long *addr1, extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size); extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size); +unsigned long _find_and_set_bit(volatile unsigned long *addr, unsigned long nbits); +unsigned long _find_and_set_next_bit(volatile unsigned long *addr, unsigned long nbits, + unsigned long start); +unsigned long _find_and_set_bit_lock(volatile unsigned long *addr, unsigned long nbits); +unsigned long _find_and_set_next_bit_lock(volatile unsigned long *addr, unsigned long nbits, + unsigned long start); +unsigned long _find_and_clear_bit(volatile unsigned long *addr, unsigned long nbits); +unsigned long _find_and_clear_next_bit(volatile unsigned long *addr, unsigned long nbits, + unsigned long start); + #ifdef __BIG_ENDIAN unsigned long _find_first_zero_bit_le(const unsigned long *addr, unsigned long size); unsigned long _find_next_zero_bit_le(const unsigned long *addr, unsigned @@ -460,6 +470,267 @@ unsigned long __for_each_wrap(const unsigned long *bitmap, unsigned long size, return bit < start ? bit : size; } +/** + * find_and_set_bit - Find a zero bit and set it atomically + * @addr: The address to base the search on + * @nbits: The bitmap size in bits + * + * This function is designed to operate in concurrent access environment. + * + * Because of concurrency and volatile nature of underlying bitmap, it's not + * guaranteed that the bit found is the 1st bit in the bitmap. It's also not + * guaranteed that if @nbits is returned, the bitmap is empty. + * + * The function does guarantee that if returned value is in range [0 .. @nbits), + * the acquired bit belongs to the caller exclusively. + * + * Returns: found and set bit, or @nbits if no bits found + */ +static inline +unsigned long find_and_set_bit(volatile unsigned long *addr, unsigned long nbits) +{ + if (small_const_nbits(nbits)) { + unsigned long val, ret; + + do { + val = *addr | ~GENMASK(nbits - 1, 0); + if (val == ~0UL) + return nbits; + ret = ffz(val); + } while (test_and_set_bit(ret, addr)); + + return ret; + } + + return _find_and_set_bit(addr, nbits); +} + + +/** + * find_and_set_next_bit - Find a zero bit and set it, starting from @offset + * @addr: The address to base the search on + * @nbits: The bitmap nbits in bits + * @offset: The bitnumber to start searching at + * + * This function is designed to operate in concurrent access environment. + * + * Because of concurrency and volatile nature of underlying bitmap, it's not + * guaranteed that the bit found is the 1st bit in the bitmap, starting from @offset. + * It's also not guaranteed that if @nbits is returned, the bitmap is empty. + * + * The function does guarantee that if returned value is in range [@offset .. @nbits), + * the acquired bit belongs to the caller exclusively. + * + * Returns: found and set bit, or @nbits if no bits found + */ +static inline +unsigned long find_and_set_next_bit(volatile unsigned long *addr, + unsigned long nbits, unsigned long offset) +{ + if (small_const_nbits(nbits)) { + unsigned long val, ret; + + do { + val = *addr | ~GENMASK(nbits - 1, offset); + if (val == ~0UL) + return nbits; + ret = ffz(val); + } while (test_and_set_bit(ret, addr)); + + return ret; + } + + return _find_and_set_next_bit(addr, nbits, offset); +} + +/** + * find_and_set_bit_wrap - find and set bit starting at @offset, wrapping around zero + * @addr: The first address to base the search on + * @nbits: The bitmap size in bits + * @offset: The bitnumber to start searching at + * + * Returns: the bit number for the next clear bit, or first clear bit up to @offset, + * while atomically setting it. If no bits are found, returns @nbits. + */ +static inline +unsigned long find_and_set_bit_wrap(volatile unsigned long *addr, + unsigned long nbits, unsigned long offset) +{ + unsigned long bit = find_and_set_next_bit(addr, nbits, offset); + + if (bit < nbits || offset == 0) + return bit; + + bit = find_and_set_bit(addr, offset); + return bit < offset ? bit : nbits; +} + +/** + * find_and_set_bit_lock - find a zero bit, then set it atomically with lock + * @addr: The address to base the search on + * @nbits: The bitmap nbits in bits + * + * This function is designed to operate in concurrent access environment. + * + * Because of concurrency and volatile nature of underlying bitmap, it's not + * guaranteed that the bit found is the 1st bit in the bitmap. It's also not + * guaranteed that if @nbits is returned, the bitmap is empty. + * + * The function does guarantee that if returned value is in range [0 .. @nbits), + * the acquired bit belongs to the caller exclusively. + * + * Returns: found and set bit, or @nbits if no bits found + */ +static inline +unsigned long find_and_set_bit_lock(volatile unsigned long *addr, unsigned long nbits) +{ + if (small_const_nbits(nbits)) { + unsigned long val, ret; + + do { + val = *addr | ~GENMASK(nbits - 1, 0); + if (val == ~0UL) + return nbits; + ret = ffz(val); + } while (test_and_set_bit_lock(ret, addr)); + + return ret; + } + + return _find_and_set_bit_lock(addr, nbits); +} + +/** + * find_and_set_next_bit_lock - find a zero bit and set it atomically with lock + * @addr: The address to base the search on + * @nbits: The bitmap size in bits + * @offset: The bitnumber to start searching at + * + * This function is designed to operate in concurrent access environment. + * + * Because of concurrency and volatile nature of underlying bitmap, it's not + * guaranteed that the bit found is the 1st bit in the range. It's also not + * guaranteed that if @nbits is returned, the bitmap is empty. + * + * The function does guarantee that if returned value is in range [@offset .. @nbits), + * the acquired bit belongs to the caller exclusively. + * + * Returns: found and set bit, or @nbits if no bits found + */ +static inline +unsigned long find_and_set_next_bit_lock(volatile unsigned long *addr, + unsigned long nbits, unsigned long offset) +{ + if (small_const_nbits(nbits)) { + unsigned long val, ret; + + do { + val = *addr | ~GENMASK(nbits - 1, offset); + if (val == ~0UL) + return nbits; + ret = ffz(val); + } while (test_and_set_bit_lock(ret, addr)); + + return ret; + } + + return _find_and_set_next_bit_lock(addr, nbits, offset); +} + +/** + * find_and_set_bit_wrap_lock - find zero bit starting at @ofset and set it + * with lock, and wrap around zero if nothing found + * @addr: The first address to base the search on + * @nbits: The bitmap size in bits + * @offset: The bitnumber to start searching at + * + * Returns: the bit number for the next set bit, or first set bit up to @offset + * If no bits are set, returns @nbits. + */ +static inline +unsigned long find_and_set_bit_wrap_lock(volatile unsigned long *addr, + unsigned long nbits, unsigned long offset) +{ + unsigned long bit = find_and_set_next_bit_lock(addr, nbits, offset); + + if (bit < nbits || offset == 0) + return bit; + + bit = find_and_set_bit_lock(addr, offset); + return bit < offset ? bit : nbits; +} + +/** + * find_and_clear_bit - Find a set bit and clear it atomically + * @addr: The address to base the search on + * @nbits: The bitmap nbits in bits + * + * This function is designed to operate in concurrent access environment. + * + * Because of concurrency and volatile nature of underlying bitmap, it's not + * guaranteed that the found bit is the 1st bit in the bitmap. It's also not + * guaranteed that if @nbits is returned, the bitmap is empty. + * + * The function does guarantee that if returned value is in range [0 .. @nbits), + * the acquired bit belongs to the caller exclusively. + * + * Returns: found and cleared bit, or @nbits if no bits found + */ +static inline unsigned long find_and_clear_bit(volatile unsigned long *addr, unsigned long nbits) +{ + if (small_const_nbits(nbits)) { + unsigned long val, ret; + + do { + val = *addr & GENMASK(nbits - 1, 0); + if (val == 0) + return nbits; + ret = __ffs(val); + } while (!test_and_clear_bit(ret, addr)); + + return ret; + } + + return _find_and_clear_bit(addr, nbits); +} + +/** + * find_and_clear_next_bit - Find a set bit next after @offset, and clear it atomically + * @addr: The address to base the search on + * @nbits: The bitmap nbits in bits + * @offset: bit offset at which to start searching + * + * This function is designed to operate in concurrent access environment. + * + * Because of concurrency and volatile nature of underlying bitmap, it's not + * guaranteed that the bit found is the 1st bit in the range It's also not + * guaranteed that if @nbits is returned, there's no set bits after @offset. + * + * The function does guarantee that if returned value is in range [@offset .. @nbits), + * the acquired bit belongs to the caller exclusively. + * + * Returns: found and cleared bit, or @nbits if no bits found + */ +static inline +unsigned long find_and_clear_next_bit(volatile unsigned long *addr, + unsigned long nbits, unsigned long offset) +{ + if (small_const_nbits(nbits)) { + unsigned long val, ret; + + do { + val = *addr & GENMASK(nbits - 1, offset); + if (val == 0) + return nbits; + ret = __ffs(val); + } while (!test_and_clear_bit(ret, addr)); + + return ret; + } + + return _find_and_clear_next_bit(addr, nbits, offset); +} + /** * find_next_clump8 - find next 8-bit clump with set bits in a memory region * @clump: location to store copy of found clump @@ -577,6 +848,24 @@ unsigned long find_next_bit_le(const void *addr, unsigned #define for_each_set_bit_from(bit, addr, size) \ for (; (bit) = find_next_bit((addr), (size), (bit)), (bit) < (size); (bit)++) +/* same as for_each_set_bit() but atomically clears each found bit */ +#define for_each_test_and_clear_bit(bit, addr, size) \ + for ((bit) = 0; \ + (bit) = find_and_clear_next_bit((addr), (size), (bit)), (bit) < (size); \ + (bit)++) + +/* same as for_each_clear_bit() but atomically sets each found bit */ +#define for_each_test_and_set_bit(bit, addr, size) \ + for ((bit) = 0; \ + (bit) = find_and_clear_next_bit((addr), (size), (bit)), (bit) < (size); \ + (bit)++) + +/* same as for_each_clear_bit_from() but atomically clears each found bit */ +#define for_each_test_and_set_bit_from(bit, addr, size) \ + for (; \ + (bit) = find_and_set_next_bit((addr), (size), (bit)), (bit) < (size); \ + (bit)++) + #define for_each_clear_bit(bit, addr, size) \ for ((bit) = 0; \ (bit) = find_next_zero_bit((addr), (size), (bit)), (bit) < (size); \ diff --git a/lib/find_bit.c b/lib/find_bit.c index 32f99e9a670e..c9b6b9f96610 100644 --- a/lib/find_bit.c +++ b/lib/find_bit.c @@ -116,6 +116,91 @@ unsigned long _find_first_and_bit(const unsigned long *addr1, EXPORT_SYMBOL(_find_first_and_bit); #endif +unsigned long _find_and_set_bit(volatile unsigned long *addr, unsigned long nbits) +{ + unsigned long bit; + + do { + bit = FIND_FIRST_BIT(~addr[idx], /* nop */, nbits); + if (bit >= nbits) + return nbits; + } while (test_and_set_bit(bit, addr)); + + return bit; +} +EXPORT_SYMBOL(_find_and_set_bit); + +unsigned long _find_and_set_next_bit(volatile unsigned long *addr, + unsigned long nbits, unsigned long start) +{ + unsigned long bit; + + do { + bit = FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start); + if (bit >= nbits) + return nbits; + } while (test_and_set_bit(bit, addr)); + + return bit; +} +EXPORT_SYMBOL(_find_and_set_next_bit); + +unsigned long _find_and_set_bit_lock(volatile unsigned long *addr, unsigned long nbits) +{ + unsigned long bit; + + do { + bit = FIND_FIRST_BIT(~addr[idx], /* nop */, nbits); + if (bit >= nbits) + return nbits; + } while (test_and_set_bit_lock(bit, addr)); + + return bit; +} +EXPORT_SYMBOL(_find_and_set_bit_lock); + +unsigned long _find_and_set_next_bit_lock(volatile unsigned long *addr, + unsigned long nbits, unsigned long start) +{ + unsigned long bit; + + do { + bit = FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start); + if (bit >= nbits) + return nbits; + } while (test_and_set_bit_lock(bit, addr)); + + return bit; +} +EXPORT_SYMBOL(_find_and_set_next_bit_lock); + +unsigned long _find_and_clear_bit(volatile unsigned long *addr, unsigned long nbits) +{ + unsigned long bit; + + do { + bit = FIND_FIRST_BIT(addr[idx], /* nop */, nbits); + if (bit >= nbits) + return nbits; + } while (!test_and_clear_bit(bit, addr)); + + return bit; +} +EXPORT_SYMBOL(_find_and_clear_bit); + +unsigned long _find_and_clear_next_bit(volatile unsigned long *addr, + unsigned long nbits, unsigned long start) +{ + do { + start = FIND_NEXT_BIT(addr[idx], /* nop */, nbits, start); + if (start >= nbits) + return nbits; + } while (!test_and_clear_bit(start, addr)); + + return start; +} +EXPORT_SYMBOL(_find_and_clear_next_bit); + #ifndef find_first_zero_bit /* * Find the first cleared bit in a memory region. From patchwork Sat Nov 18 15:50:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13460139 X-Patchwork-Delegate: kuba@kernel.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fH6IUlnK" Received: from mail-yb1-xb29.google.com (mail-yb1-xb29.google.com [IPv6:2607:f8b0:4864:20::b29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A799F1BD4; Sat, 18 Nov 2023 07:51:39 -0800 (PST) Received: by mail-yb1-xb29.google.com with SMTP id 3f1490d57ef6-da819902678so2850616276.1; Sat, 18 Nov 2023 07:51:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700322698; x=1700927498; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MVDnPRtaRLazzNSQqeYFzsOLIVc3PVHkJ3Smdo81+fM=; b=fH6IUlnKl+XJ2/OuYFTx23RstVGtGSlGFQ/3+xlroLXDu1iCWEociJ0i4qjs+HhfEO aOtwuhCaKCn7N8R9ulrKmvt4zGkgL7KmefwSS7195RiI72CX5L4ijY+RYDxqavdqTV+p +QBshJ9+oMGQvxhCvauk98tZur/evaRPmpJsAoCYoZy2Tb5OKqqszoCNwuVCMnlNDyli qzi6MZ7EwJpElz7mSyM11yFwcUpU3M5Yju7pLfZz6aS11EsbRQG4Hq6lYFslYBY8w/Vx atEKoMayU0rr/A8RMw6MDDnGuHW/QKvL/5CqcjIqhRyTfjN8X/8v9tbPw+v3CbFo914V OpxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700322698; x=1700927498; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MVDnPRtaRLazzNSQqeYFzsOLIVc3PVHkJ3Smdo81+fM=; b=eUFVJ/I3c6HsTpn6yVhaxaa7ggfFTiZExzEdL7k7TgltVCHgxwh9Te/HU78iWKbNef mvYGpGLKhqbwhMW8N/QUQSlS7YtLLMXBK65rqTWi/lhcD4FwlV2DX5znt8tJK7fPMkTZ ZUE7Ts7WF5tDXSbLRy1rta/I9Bxi/wWkK7IGbvPwoZsFpSj6jchUjyk/TuxU6a1TIVgR ACu4e8F+lCT048CmIXf3gsEojWBWFOYtu9Z1Opoa2FP6E+ufNxZ/LAEwOMrRN2UyvhqA 4fA7zV9ii6twWTk/e36KL4DlVVlw83h3NLHSFA06h6x/ap4/lXzEs96JkfnBfhld1M5e JZIQ== X-Gm-Message-State: AOJu0Yzqtkc6PYBlKcP3kf941lOT5TJm9olg/hXHoEGSDc/VUGGDCHrU zMT0iZtmxUCJd8Iouv9yl57hLl6jOgbN8Ok7 X-Google-Smtp-Source: AGHT+IFtv4Y5M+sXZKP4hY/boWna7OBaMWOrVT2d9mWQ309PzUbuFpqsDSmyQwNUVJs/HTlum9QHAQ== X-Received: by 2002:a5b:a12:0:b0:d9a:ba25:d1f9 with SMTP id k18-20020a5b0a12000000b00d9aba25d1f9mr2149118ybq.9.1700322697688; Sat, 18 Nov 2023 07:51:37 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:48a9:bd4c:868d:dc97]) by smtp.gmail.com with ESMTPSA id b79-20020a253452000000b00da076458395sm998958yba.43.2023.11.18.07.51.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Nov 2023 07:51:36 -0800 (PST) From: Yury Norov To: linux-kernel@vger.kernel.org, Edward Cree , Martin Habets , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Yury Norov , netdev@vger.kernel.org, linux-net-drivers@amd.com Cc: Jan Kara , Mirsad Todorovac , Matthew Wilcox , Rasmus Villemoes , Andy Shevchenko , Maxim Kuvyrkov , Alexey Klimov Subject: [PATCH 19/34] sfc: switch to using atomic find_bit() API where appropriate Date: Sat, 18 Nov 2023 07:50:50 -0800 Message-Id: <20231118155105.25678-20-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231118155105.25678-1-yury.norov@gmail.com> References: <20231118155105.25678-1-yury.norov@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org SFC code traverses rps_slot_map and rxq_retry_mask bit by bit. We can do it better by using dedicated atomic find_bit() functions, because they skip already clear bits. Signed-off-by: Yury Norov Reviewed-by: Edward Cree --- drivers/net/ethernet/sfc/rx_common.c | 4 +--- drivers/net/ethernet/sfc/siena/rx_common.c | 4 +--- drivers/net/ethernet/sfc/siena/siena_sriov.c | 14 ++++++-------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c index d2f35ee15eff..0112968b3fe7 100644 --- a/drivers/net/ethernet/sfc/rx_common.c +++ b/drivers/net/ethernet/sfc/rx_common.c @@ -950,9 +950,7 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, int rc; /* find a free slot */ - for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++) - if (!test_and_set_bit(slot_idx, &efx->rps_slot_map)) - break; + slot_idx = find_and_set_bit(&efx->rps_slot_map, EFX_RPS_MAX_IN_FLIGHT); if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT) return -EBUSY; diff --git a/drivers/net/ethernet/sfc/siena/rx_common.c b/drivers/net/ethernet/sfc/siena/rx_common.c index 4579f43484c3..160b16aa7486 100644 --- a/drivers/net/ethernet/sfc/siena/rx_common.c +++ b/drivers/net/ethernet/sfc/siena/rx_common.c @@ -958,9 +958,7 @@ int efx_siena_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, int rc; /* find a free slot */ - for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++) - if (!test_and_set_bit(slot_idx, &efx->rps_slot_map)) - break; + slot_idx = find_and_set_bit(&efx->rps_slot_map, EFX_RPS_MAX_IN_FLIGHT); if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT) return -EBUSY; diff --git a/drivers/net/ethernet/sfc/siena/siena_sriov.c b/drivers/net/ethernet/sfc/siena/siena_sriov.c index 8353c15dc233..554b799288b8 100644 --- a/drivers/net/ethernet/sfc/siena/siena_sriov.c +++ b/drivers/net/ethernet/sfc/siena/siena_sriov.c @@ -722,14 +722,12 @@ static int efx_vfdi_fini_all_queues(struct siena_vf *vf) efx_vfdi_flush_wake(vf), timeout); rxqs_count = 0; - for (index = 0; index < count; ++index) { - if (test_and_clear_bit(index, vf->rxq_retry_mask)) { - atomic_dec(&vf->rxq_retry_count); - MCDI_SET_ARRAY_DWORD( - inbuf, FLUSH_RX_QUEUES_IN_QID_OFST, - rxqs_count, vf_offset + index); - rxqs_count++; - } + for_each_test_and_clear_bit(index, vf->rxq_retry_mask, count) { + atomic_dec(&vf->rxq_retry_count); + MCDI_SET_ARRAY_DWORD( + inbuf, FLUSH_RX_QUEUES_IN_QID_OFST, + rxqs_count, vf_offset + index); + rxqs_count++; } } From patchwork Sat Nov 18 15:50:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13460140 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CliZe3Tk" Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 85E921FC6; Sat, 18 Nov 2023 07:51:46 -0800 (PST) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-5a86b6391e9so34000057b3.0; Sat, 18 Nov 2023 07:51:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700322704; x=1700927504; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0d2eKvr3TXuVBrgKyJ84PHfbsLaO9M1lKSW9z0G3/1I=; b=CliZe3TkN7RwUCns6Euw1bJup2j6ayFXl5NT81h8uTPGUvhdBUh5diVVPsw3bAbv27 WZ2XqtPAIvvkC7CD0hD9ixz4h1RcDLrTHRS74k6yrVGcpAiwFT2AGBj0AU7of/fywI/L JTTng5KOCH3F3F3JG5l4LczIrrFtSuo46cgoPeRbag2VvuLz7te8cEiyJA9x5SqAc1kh K6jXIdOvZhFRpD6r4hAFZf6CykGW9soyWPMRYXBM86k5SaLBbiFH6ulPZlWh+Ur7AbFu SLkqGLq07GRBd3MckE6gBcEmhEzwiHsA3J+7Abja/qAvN0ewCQxmvDr8ZSfEaekFZKXm 5+TA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700322704; x=1700927504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0d2eKvr3TXuVBrgKyJ84PHfbsLaO9M1lKSW9z0G3/1I=; b=v8DWeUGOsMEG/nOvZRXGtQNXetznK5b3gSHY4FMsJ8voW2KhCYXJDp74yXgG4jmx4B Wy9Gau/uMpkHhVxMJt7zmBzljsdJ+36A3OtccYlnIudugKhjJN4/BiuSvZb2ywamXYSz 2Bb6vfTV4At9BxwHjxbtLckWpxn601w2TFmsmvCcmenZ1nFPyvmWlasTvDvZYOXMMRod Cl0INW2+LHrQKCAupymrRRoYbzqyA2+cOYckP9Ra28SZEE/xp7pKkwze5ah8DWk7emD6 Bi5KUwp/U7SQ6+Uu6RBtgmkedDDa6BYDFH1KMmXnXDpRkPVoFHS34SakTDxdTL/Epbrh ctjg== X-Gm-Message-State: AOJu0Yyq9LqF2t7qh5s0Wd4QMBlkDaTzp3ujSBGrTvuYla/skZJYY73y 18FYq+3z3tuDesfzS9/tv8xd7W1czoz0mznF X-Google-Smtp-Source: AGHT+IELqoxPTAIh1lB3sdLeAXBXNyn+zXCWPkZuWXsEeemBrT9Rti9Mc1tneRNCARA0PmaLxTdqxw== X-Received: by 2002:a05:690c:2a85:b0:5af:66e7:e382 with SMTP id ek5-20020a05690c2a8500b005af66e7e382mr2522479ywb.34.1700322704464; Sat, 18 Nov 2023 07:51:44 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:48a9:bd4c:868d:dc97]) by smtp.gmail.com with ESMTPSA id q126-20020a815c84000000b005a7c829dda2sm1170423ywb.84.2023.11.18.07.51.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Nov 2023 07:51:44 -0800 (PST) From: Yury Norov To: linux-kernel@vger.kernel.org, Karsten Keil , netdev@vger.kernel.org Cc: Yury Norov , Jan Kara , Mirsad Todorovac , Matthew Wilcox , Rasmus Villemoes , Andy Shevchenko , Maxim Kuvyrkov , Alexey Klimov Subject: [PATCH 24/34] mISDN: optimize get_free_devid() Date: Sat, 18 Nov 2023 07:50:55 -0800 Message-Id: <20231118155105.25678-25-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231118155105.25678-1-yury.norov@gmail.com> References: <20231118155105.25678-1-yury.norov@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 get_free_devid() traverses each bit in device_ids in an open-coded loop. We can do it faster by using dedicated find_and_set_bit(). It makes the whole function a nice one-liner, and because MAX_DEVICE_ID is a small constant-time value (63), on 64-bit platforms find_and_set_bit() call will be optimized to: ffs(); test_and_set_bit(). Signed-off-by: Yury Norov --- drivers/isdn/mISDN/core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c index ab8513a7acd5..3f97db006cf3 100644 --- a/drivers/isdn/mISDN/core.c +++ b/drivers/isdn/mISDN/core.c @@ -197,14 +197,9 @@ get_mdevice_count(void) static int get_free_devid(void) { - u_int i; + u_int i = find_and_set_bit((u_long *)&device_ids, MAX_DEVICE_ID + 1); - for (i = 0; i <= MAX_DEVICE_ID; i++) - if (!test_and_set_bit(i, (u_long *)&device_ids)) - break; - if (i > MAX_DEVICE_ID) - return -EBUSY; - return i; + return i <= MAX_DEVICE_ID ? i : -EBUSY; } int From patchwork Sat Nov 18 15:50:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13460141 X-Patchwork-Delegate: kuba@kernel.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="S4GwRONQ" Received: from mail-yw1-x112a.google.com (mail-yw1-x112a.google.com [IPv6:2607:f8b0:4864:20::112a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF76A1FD9; Sat, 18 Nov 2023 07:51:48 -0800 (PST) Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-5c516f92759so32038617b3.2; Sat, 18 Nov 2023 07:51:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700322708; x=1700927508; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fm1bHPEyELp3MiPjOSu0bHDojYqM84986duNSStQHBY=; b=S4GwRONQN6Sg7Bq0l5QNXv2PN7PtyWj4PbeIQm1D0PgHld0Aue9+G9wJIa3+VR6r4N 69fckYz3ZFtTSrTmp3wBm9HgI4AFnN9oP8kq2NFoUF7zI5qMGuq0QfN8uWOwRlPcugwb SgsXAzhcRoKLyTeBcAykIkmKaVsdwZTdnJ5oMwlTmUIrFNm6hE7uIZwbfaRavFTiFbSN vgLIi9Doss0CR/kd4xoJudiEEg0LxDUQSmpsoAPa9Rmil3o3cEkzZkK+0SN5LNZQnmG0 AT8q/gLHLLhO5bFeMeduSD7QNmlMQ2PI9YysiarzIbxyaKqkuWP1uhYJj7ntZbz/adua lqdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700322708; x=1700927508; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fm1bHPEyELp3MiPjOSu0bHDojYqM84986duNSStQHBY=; b=GvT1qHTA1uEw494ni2VTjuK/ejdoxx2W4wC6b86eetyhkRQcvwqLVuPHZqngQNHWE9 dH4nYSxgs41Au6dTRF9+wxsmX1DMAdGL7VCzEidM3cTZGwg1rs/eU/bEz0zTRhR/U9Cv 4+s+twvmyjJy2dfHPNz27sxaCqP7cz7hoyB0d8Z8tZ+36nFIJD2LMr98ongzkb7HAhpm mQUe43NT0Q9kPYAErdfb28epsXkRnD2REq0gxnuFzu5G+q9qlahmAT24manx57LN1lPJ OrJhi7ujbDrip45E/9MuE9on4tDNZSIDVWJ11mMeaERVCsriDnS1kjXNYTS+PA6WFcoX Phkw== X-Gm-Message-State: AOJu0YxMJB6d2rNmyaG7G7trBdICttbdfXUClSnpYrs9S3nhXHKBdK0e ZNaImNiBiHR4RDMbCI7KngBlwAnUSXF289po X-Google-Smtp-Source: AGHT+IEr9EXnIrnz3KfJlWeIhC3M3/FUV0iAGcHYIcYOW9tXgSnWoyx3lY1GC4qxv/GhgpzHagmIGw== X-Received: by 2002:a81:ef0d:0:b0:59b:5696:c33 with SMTP id o13-20020a81ef0d000000b0059b56960c33mr2780375ywm.46.1700322707666; Sat, 18 Nov 2023 07:51:47 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:48a9:bd4c:868d:dc97]) by smtp.gmail.com with ESMTPSA id b65-20020a0dd944000000b005a8c392f498sm1167821ywe.82.2023.11.18.07.51.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Nov 2023 07:51:46 -0800 (PST) From: Yury Norov To: linux-kernel@vger.kernel.org, Jiri Pirko , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: Yury Norov , Jan Kara , Mirsad Todorovac , Matthew Wilcox , Rasmus Villemoes , Andy Shevchenko , Maxim Kuvyrkov , Alexey Klimov Subject: [PATCH 26/34] ethernet: rocker: optimize ofdpa_port_internal_vlan_id_get() Date: Sat, 18 Nov 2023 07:50:57 -0800 Message-Id: <20231118155105.25678-27-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231118155105.25678-1-yury.norov@gmail.com> References: <20231118155105.25678-1-yury.norov@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Optimize ofdpa_port_internal_vlan_id_get() by using find_and_set_bit(), instead of polling every bit from bitmap in a for-loop. Signed-off-by: Yury Norov --- drivers/net/ethernet/rocker/rocker_ofdpa.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c index 826990459fa4..449be8af7ffc 100644 --- a/drivers/net/ethernet/rocker/rocker_ofdpa.c +++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c @@ -2249,14 +2249,11 @@ static __be16 ofdpa_port_internal_vlan_id_get(struct ofdpa_port *ofdpa_port, found = entry; hash_add(ofdpa->internal_vlan_tbl, &found->entry, found->ifindex); - for (i = 0; i < OFDPA_N_INTERNAL_VLANS; i++) { - if (test_and_set_bit(i, ofdpa->internal_vlan_bitmap)) - continue; + i = find_and_set_bit(ofdpa->internal_vlan_bitmap, OFDPA_N_INTERNAL_VLANS); + if (i < OFDPA_N_INTERNAL_VLANS) found->vlan_id = htons(OFDPA_INTERNAL_VLAN_ID_BASE + i); - goto found; - } - - netdev_err(ofdpa_port->dev, "Out of internal VLAN IDs\n"); + else + netdev_err(ofdpa_port->dev, "Out of internal VLAN IDs\n"); found: found->ref_count++; From patchwork Sat Nov 18 15:50:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13460142 X-Patchwork-Delegate: kuba@kernel.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XHFM6tKQ" Received: from mail-yw1-x1133.google.com (mail-yw1-x1133.google.com [IPv6:2607:f8b0:4864:20::1133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1500D1FEB; Sat, 18 Nov 2023 07:51:52 -0800 (PST) Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-5c9adcaf514so407127b3.2; Sat, 18 Nov 2023 07:51:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700322710; x=1700927510; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5/FFRxNdIVmBtGkGik+eY+kvUwCYYAdIhZdGmVH5ny0=; b=XHFM6tKQUtr+ERDMSFScqY8TpsnBRXCGYuutGO0nb1jrhv7VWiCmz8vSZpRl3H4EXu NFFvC0GFb4qTtkyiEroiLv8JYpXsun4dWahd/cWc+aTR+916BWvMI7BLQCQuSJ6Fjx6s 090ZZr+pw0FC4Bq1GekOw4/eCTAka5QBvtAP78FJ61Ps42T/bDARzMy98D/iZfaF6UQy a6d+X6NSxvFmKGCYr7Krt+yLnooXahSheZ5psFFQElE+6wVU/Qg4ImNxK3eZUs/xp/2G 6wYVpt4CIuhipxn2oo1Jcp08zqJr6C9XjNOupeVlIjjqab8ENkNrALLPhWq33QZFI0FB GFNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700322710; x=1700927510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5/FFRxNdIVmBtGkGik+eY+kvUwCYYAdIhZdGmVH5ny0=; b=Ct4nzdt4mx15hxHbv9hsQAhX2ZtgICGYJzYRlqHiHPRHJa6oEGKJrH7qdylsNj3fTL sJJSB0rcQCe5oR1diK6OgnhPWyDBnYIadr+BiR5o2D0ivbOPEBAC8lGnx02/6l+7ltgI 2IwAy4Gh1TEPeN9Cw9SejC0a5jb3BGCsPobEwVGuUyYcGKXzHeaBA7s0MBDEp5K3E0NK y6OrDPCOWXEZkU63RC3GSf4EGndtCdoy3sI7N4OS/W3G9blvqoRYkHUwXD9+zoZ52iuQ er4glkaX9oODEHOnf+qZmfVM2+uaDndlXBRNDZHMqxxZAOiaSvAhK/7aG0WEPc3kY2Vm 3dqw== X-Gm-Message-State: AOJu0YzJqz7WaDwT8PabL6YOTwuYEF3To1B16tJSGFBNFCnd9T2Ywmhw wISDFCj8etrArWmi3LoI2uXtgy5vyjUKZmyU X-Google-Smtp-Source: AGHT+IGMZW2BXhTq6urOTFJBRfGUnn7sVaNNC8L1hFUdeATS2oy7Q8NxWcEEhUoAcnJ9H9mWRS92oA== X-Received: by 2002:a0d:d951:0:b0:5a7:d412:af32 with SMTP id b78-20020a0dd951000000b005a7d412af32mr2476093ywe.10.1700322710270; Sat, 18 Nov 2023 07:51:50 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:48a9:bd4c:868d:dc97]) by smtp.gmail.com with ESMTPSA id i205-20020a8154d6000000b0059bcadded9dsm1176063ywb.116.2023.11.18.07.51.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Nov 2023 07:51:49 -0800 (PST) From: Yury Norov To: linux-kernel@vger.kernel.org, Karsten Keil , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Yury Norov , netdev@vger.kernel.org, linux-bluetooth@vger.kernel.org Cc: Jan Kara , Mirsad Todorovac , Matthew Wilcox , Rasmus Villemoes , Andy Shevchenko , Maxim Kuvyrkov , Alexey Klimov Subject: [PATCH 28/34] bluetooth: optimize cmtp_alloc_block_id() Date: Sat, 18 Nov 2023 07:50:59 -0800 Message-Id: <20231118155105.25678-29-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231118155105.25678-1-yury.norov@gmail.com> References: <20231118155105.25678-1-yury.norov@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Instead of polling every bit in blockids, switch it to using a dedicated find_and_set_bit(), and make the function a simple one-liner. Signed-off-by: Yury Norov --- net/bluetooth/cmtp/core.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 90d130588a3e..b1330acbbff3 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -88,15 +88,9 @@ static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_connin static inline int cmtp_alloc_block_id(struct cmtp_session *session) { - int i, id = -1; + int id = find_and_set_bit(&session->blockids, 16); - for (i = 0; i < 16; i++) - if (!test_and_set_bit(i, &session->blockids)) { - id = i; - break; - } - - return id; + return id < 16 ? id : -1; } static inline void cmtp_free_block_id(struct cmtp_session *session, int id) From patchwork Sat Nov 18 15:51:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13460143 X-Patchwork-Delegate: kuba@kernel.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IT8+IBr/" Received: from mail-yb1-xb34.google.com (mail-yb1-xb34.google.com [IPv6:2607:f8b0:4864:20::b34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27F821FF3; Sat, 18 Nov 2023 07:51:54 -0800 (PST) Received: by mail-yb1-xb34.google.com with SMTP id 3f1490d57ef6-da3b4b7c6bdso2917083276.2; Sat, 18 Nov 2023 07:51:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700322712; x=1700927512; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FRJAi9fqLnpZBQBfWveY0fRnarAyBBO44GyImL+GpQw=; b=IT8+IBr/GjwsHiuzp7JbGVGoUMD6y1ZMGmXhJaeFaN9TrOcyttSLuKo4qdu1SmXbcG VgMptIT0UAnXXPkr+htmJdWc8gttbfZJkgEawCYNoL3m1PmHFpTdb/1VYtDUa07e+tWc YjIfSHyIXopdgUYFRwTlxcaaOtQKI762QKvW8zdhLUU+jOHItUV2D9HlB/xKYgi2d27J Tx+DKwf0B/ilLwI6vSXqzgjVkD61+aQRmW9T+9xlfrfdXzy9qxHVkFY/cat075drS2di /foAu1lF96mWe7J41kM2yRloUptbCXY6fjPpShM53bkrQJ+krv3IFOWamSUUxClDXG39 4i5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700322712; x=1700927512; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FRJAi9fqLnpZBQBfWveY0fRnarAyBBO44GyImL+GpQw=; b=mDBnc/xl3/t16XUHfApkuAktgGMjkyxeKEp9vBN0+hxNFXHTqEHzokNr9YK+VsAsKF FTOEo88in//BEuOU0B3wE8a0L9+6hYJj6TTNznIDk6yy2RaI95MssBIIKBq3Pd0NqI2z wDmH0xpka0HJQ8tgr3kdtTHoi8X0k4U4itbl1aEUWeTU4MKfRPQx3L6BrlEsMVUilQOE aw9m9jzk/Ciy6b3vDILc+FOIFiXzC2zN4SUIe+v+grOfQSWlrcugQQI22Xikx7qyYfVd L+leu3AqRb6r2KsJ0iU0Hv0PYJOwZQ/KjYo7Cnn9/kSZ+yzld/NPLvH/drU8h4DrTGA+ KPSQ== X-Gm-Message-State: AOJu0Yy+Fkdbs3cozq22sc2AkHohJpbMBiASZs2x7WLhVxu9P0cdIjUm 8J08UJJ4YcruDo/4vry5oWqTLuzICP1NQ/lp X-Google-Smtp-Source: AGHT+IElJ0U3CjFZG+s3NnFjnzuVmrFeyc2e4WM5oO3xxPOV5mRPbrBHmRloD2DElouQFvaTAENskA== X-Received: by 2002:a05:6902:212:b0:d9a:d7a5:e445 with SMTP id j18-20020a056902021200b00d9ad7a5e445mr2342423ybs.49.1700322711961; Sat, 18 Nov 2023 07:51:51 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:48a9:bd4c:868d:dc97]) by smtp.gmail.com with ESMTPSA id e62-20020a25a3c4000000b00da10d9e96cesm1006690ybi.35.2023.11.18.07.51.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Nov 2023 07:51:51 -0800 (PST) From: Yury Norov To: linux-kernel@vger.kernel.org, Karsten Graul , Wenjia Zhang , Jan Karcher , "D. Wythe" , Tony Lu , Wen Gu , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-s390@vger.kernel.org, netdev@vger.kernel.org Cc: Yury Norov , Jan Kara , Mirsad Todorovac , Matthew Wilcox , Rasmus Villemoes , Andy Shevchenko , Maxim Kuvyrkov , Alexey Klimov Subject: [PATCH 29/34] net: smc: fix opencoded find_and_set_bit() in smc_wr_tx_get_free_slot_index() Date: Sat, 18 Nov 2023 07:51:00 -0800 Message-Id: <20231118155105.25678-30-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231118155105.25678-1-yury.norov@gmail.com> References: <20231118155105.25678-1-yury.norov@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org The function opencodes find_and_set_bit() with a for_each() loop. Fix it, and make the whole function a simple almost one-liner. Signed-off-by: Yury Norov --- net/smc/smc_wr.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c index 0021065a600a..b6f0cfc52788 100644 --- a/net/smc/smc_wr.c +++ b/net/smc/smc_wr.c @@ -170,15 +170,11 @@ void smc_wr_tx_cq_handler(struct ib_cq *ib_cq, void *cq_context) static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx) { - *idx = link->wr_tx_cnt; if (!smc_link_sendable(link)) return -ENOLINK; - for_each_clear_bit(*idx, link->wr_tx_mask, link->wr_tx_cnt) { - if (!test_and_set_bit(*idx, link->wr_tx_mask)) - return 0; - } - *idx = link->wr_tx_cnt; - return -EBUSY; + + *idx = find_and_set_bit(link->wr_tx_mask, link->wr_tx_cnt); + return *idx < link->wr_tx_cnt ? 0 : -EBUSY; } /**