From patchwork Sun Dec 3 19:23:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13477433 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lhpJ51on" Received: from mail-qk1-x729.google.com (mail-qk1-x729.google.com [IPv6:2607:f8b0:4864:20::729]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D142BD6; Sun, 3 Dec 2023 11:24:28 -0800 (PST) Received: by mail-qk1-x729.google.com with SMTP id af79cd13be357-77dc38b4e8dso262734285a.1; Sun, 03 Dec 2023 11:24:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701631467; x=1702236267; 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=zQMxTVPAK6MFSjY9bikHe7s4rwhQ9hzDceOswvDYFYU=; b=lhpJ51on/g7X0QySsgZ95rDDmFKGysipzZ6EWdjI7aHdFhHFN3371GRF+BScNUhg4S PjWfxml1GFpYQwq/JbvB6XWmK9VwVCScmwpE+zK/RkodRgJoA9yzLt2yuJH0LK6L2Y0A Dl2116YbqxC8ao6lJ//f8TI8fksbFP1V7QY1wTmwQD7kAQHNtEreApwfGfpWmswLmGbq 4/y1pCTiSiBZ2vnnNuQ0KnrUxBGyJQ325y3z8UaD6WLyA1eMECiRFZPZH55RgwBF3kEc vGIL3HwcthUNYT6NPpIxq+nQvzPQeVOdKS13PX8RRFKcIqwmTJw8PdIeogNmLjMyyewi SaGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701631467; x=1702236267; 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=zQMxTVPAK6MFSjY9bikHe7s4rwhQ9hzDceOswvDYFYU=; b=Iyr+I6nBQdoY5rkPPWfCOXhC/TZx+UaQpMS6dJfQM4nje8r42Mk2iLK5Xbc1isi7EF jVAASpEzSYE4eP2GJjDN4GvqSrk2qvqo1p9JI3Pcg/oduBOIjIl1nyHgFTo4aMY9UEdM ppyy6PL/bp6t+pVm06myFMN62BGdnRIp8yxIx1/DlQ9TjhdNZmHF7llzJDzXyey5shvw Lpc+lEXtTRae9vXwIMcSDStvEYJhcpMyvBBAP9/N1J/vdyh27bdPT0L/it2AZj2+Sp8k oB2AJmVpiyWhqoPCyyD4c96gBFdvbanlJROnT9eEFO+aRRvtijPQls7tYwDfcQttvdX4 AT6A== X-Gm-Message-State: AOJu0Yyb64fLqdNZi7Q9XRhQWByGmk18htGcSjDqjzITl2Ob7/r5znAS UGMhi9EKewC9hdPD/6m6jjacAljMDsdbhQ== X-Google-Smtp-Source: AGHT+IFooxiJZ8V1LpPTaQzP0LVV51jzAeTcdeLK0ZC96y8JrbBNrIJa1nUbAIA9L7CEuItTj3tUXQ== X-Received: by 2002:a05:620a:1d01:b0:77e:fba3:58bf with SMTP id dl1-20020a05620a1d0100b0077efba358bfmr4125683qkb.80.1701631466751; Sun, 03 Dec 2023 11:24:26 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:cb98:c3e:57c:8191]) by smtp.gmail.com with ESMTPSA id n14-20020a819e4e000000b0059b2be24f88sm2674090ywj.143.2023.12.03.11.24.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 11:24:26 -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 , 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 , Bart Van Assche , Sergey Shtylyov Subject: [PATCH v2 01/35] lib/find: add atomic find_bit() primitives Date: Sun, 3 Dec 2023 11:23:48 -0800 Message-Id: <20231203192422.539300-2-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231203192422.539300-1-yury.norov@gmail.com> References: <20231203192422.539300-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 to 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. Suffixes like _wrap or _lock derive their 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. CC: Bart Van Assche CC: Sergey Shtylyov Signed-off-by: Yury Norov --- include/linux/find.h | 293 +++++++++++++++++++++++++++++++++++++++++++ lib/find_bit.c | 85 +++++++++++++ 2 files changed, 378 insertions(+) diff --git a/include/linux/find.h b/include/linux/find.h index 5e4f39ef2e72..79b0e2589725 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 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 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 found bit 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 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 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 found bit 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 found bit 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,28 @@ 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_set_bit_from() but atomically clears each found bit */ +#define for_each_test_and_clear_bit_from(bit, addr, size) \ + for (; (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_set_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 Sun Dec 3 19:32:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13477464 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IrkrSono" 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 29F12E3; Sun, 3 Dec 2023 11:33:12 -0800 (PST) Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-5d81c24cef2so5020787b3.2; Sun, 03 Dec 2023 11:33:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701631990; x=1702236790; 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=HmvgTcSgTSYSGQ9OhXSlfMgozAivgkoJ1Cnrtk56obw=; b=IrkrSonodykAw39/+MwjHWDI+97PidIKPur7BWdzSboCV3J0UP6PxT855kFC9amrxI OM8mqFyqllnsGlUhKf5bKW1gYNULqCbot1URgDnRnJKbkRgFQrbP/gHmi+wIDLB+fDV2 PpbYzHEqkGn8hNl07gl2gaJfsNeS1V+6T99ZDEuRf+Q2nfEIJB7eJ0mIgFuI3/deLTmR UMZmQmVq192L4Ul1o/vqlkDsAKgKoVmqw1/rsIwIhAolyhgDgx7qFYx57jo/nu3NQUKo yPKItUoGYvHz3x/5cEag9UviH9o/znXzNC7drtll9WITH971VPhJ+Uu6RP3s8KqK3Dwu uvPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701631990; x=1702236790; 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=HmvgTcSgTSYSGQ9OhXSlfMgozAivgkoJ1Cnrtk56obw=; b=fTlgyy7np1MoKnXeEs+c9Gx7CwXzrSmE5FBgPgP6QYzBBQa6augtSGdxix+1aqBn8h oCf4R+Ifm/OWAmyW8J5wg0JJikad64rOE8QEoE/VewCg1b+1Z+Wt88tuMUywFSw//193 Ccr2exGQSYH+xsFumHdSPDLiLs7nYkeTij8KZpWkFShEspuN6cIBzTMBlpst0CkOX5Uq eozFxOX4QjBtqffNFjqSDrkTe5o0/I4wgwEauZHF6lG4XRCj9iEXZYwWBu3sGfc5lWvZ JkZxs0h60D1ntQ+6mdJBg+87BHrVM6yEusrI+V/qsNVcP7ts157ka8U0trOqjHrigrYm Zinw== X-Gm-Message-State: AOJu0Yz752gRRgMoD6y32JobW8IoYPB6y0OdTfpG9YHNZ1Ii60is2MpQ vcBvR/nNB+sV9AxqKfPSk7TA929CmPp9CQ== X-Google-Smtp-Source: AGHT+IH9dK5SBG1KTg95TkMNRGGX2LRFyEvXVyFKexhpvkq8MjiOjaHQrHY4kI3iqaUaVcCxIhY+og== X-Received: by 2002:a05:690c:c11:b0:5d1:6370:b2cf with SMTP id cl17-20020a05690c0c1100b005d16370b2cfmr2746902ywb.29.1701631990366; Sun, 03 Dec 2023 11:33:10 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:cb98:c3e:57c:8191]) by smtp.gmail.com with ESMTPSA id d143-20020a814f95000000b005d795822dc7sm1042135ywb.35.2023.12.03.11.33.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 11:33:09 -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 , 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 , Bart Van Assche , Sergey Shtylyov Subject: [PATCH v2 02/35] lib/find: add test for atomic find_bit() ops Date: Sun, 3 Dec 2023 11:32:34 -0800 Message-Id: <20231203193307.542794-1-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231203192422.539300-1-yury.norov@gmail.com> References: <20231203192422.539300-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 basic functionality test for new API. Signed-off-by: Yury Norov --- lib/test_bitmap.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index 65f22c2578b0..277e1ca9fd28 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c @@ -221,6 +221,65 @@ static void __init test_zero_clear(void) expect_eq_pbl("", bmap, 1024); } +static void __init test_find_and_bit(void) +{ + unsigned long w, w_part, bit, cnt = 0; + DECLARE_BITMAP(bmap, EXP1_IN_BITS); + + /* + * Test find_and_clear{_next}_bit() and corresponding + * iterators + */ + bitmap_copy(bmap, exp1, EXP1_IN_BITS); + w = bitmap_weight(bmap, EXP1_IN_BITS); + + for_each_test_and_clear_bit(bit, bmap, EXP1_IN_BITS) + cnt++; + + expect_eq_uint(w, cnt); + expect_eq_uint(0, bitmap_weight(bmap, EXP1_IN_BITS)); + + bitmap_copy(bmap, exp1, EXP1_IN_BITS); + w = bitmap_weight(bmap, EXP1_IN_BITS); + w_part = bitmap_weight(bmap, EXP1_IN_BITS / 3); + + cnt = 0; + bit = EXP1_IN_BITS / 3; + for_each_test_and_clear_bit_from(bit, bmap, EXP1_IN_BITS) + cnt++; + + expect_eq_uint(bitmap_weight(bmap, EXP1_IN_BITS), bitmap_weight(bmap, EXP1_IN_BITS / 3)); + expect_eq_uint(w_part, bitmap_weight(bmap, EXP1_IN_BITS)); + expect_eq_uint(w - w_part, cnt); + + /* + * Test find_and_set{_next}_bit() and corresponding + * iterators + */ + bitmap_copy(bmap, exp1, EXP1_IN_BITS); + w = bitmap_weight(bmap, EXP1_IN_BITS); + cnt = 0; + + for_each_test_and_set_bit(bit, bmap, EXP1_IN_BITS) + cnt++; + + expect_eq_uint(EXP1_IN_BITS - w, cnt); + expect_eq_uint(EXP1_IN_BITS, bitmap_weight(bmap, EXP1_IN_BITS)); + + bitmap_copy(bmap, exp1, EXP1_IN_BITS); + w = bitmap_weight(bmap, EXP1_IN_BITS); + w_part = bitmap_weight(bmap, EXP1_IN_BITS / 3); + cnt = 0; + + bit = EXP1_IN_BITS / 3; + for_each_test_and_set_bit_from(bit, bmap, EXP1_IN_BITS) + cnt++; + + expect_eq_uint(EXP1_IN_BITS - bitmap_weight(bmap, EXP1_IN_BITS), + EXP1_IN_BITS / 3 - bitmap_weight(bmap, EXP1_IN_BITS / 3)); + expect_eq_uint(EXP1_IN_BITS * 2 / 3 - (w - w_part), cnt); +} + static void __init test_find_nth_bit(void) { unsigned long b, bit, cnt = 0; @@ -1273,6 +1332,8 @@ static void __init selftest(void) test_for_each_clear_bitrange_from(); test_for_each_set_clump8(); test_for_each_set_bit_wrap(); + + test_find_and_bit(); } KSTM_MODULE_LOADERS(test_bitmap); From patchwork Sun Dec 3 19:32:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13477468 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="GODEmAyS" Received: from mail-yb1-xb2e.google.com (mail-yb1-xb2e.google.com [IPv6:2607:f8b0:4864:20::b2e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C7B019B; Sun, 3 Dec 2023 11:33:49 -0800 (PST) Received: by mail-yb1-xb2e.google.com with SMTP id 3f1490d57ef6-d9fe0a598d8so1567023276.2; Sun, 03 Dec 2023 11:33:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701632026; x=1702236826; 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=NbCVZUZWRPuqODDp3Z8qmjnrbZPazZZzGPA5ZDraoqY=; b=GODEmAySZbn4+6NIc45hfyCky5+WU1lOhnwh+FrBR9QS0IHEVYfxhI8fPUvMUtDcvf GDJQigsAR2yc45hpGZnVHUiM/zJv78OS5hpPKDM3G/v3QDwEclGqIjHBUGOY9dvAI9JS iXpBjcDxYdQsc93EVJFEuFvBUHZdZNomajmTF4HfleZlIK2ajIAeWMZndNLdGssxhnbR aIOIdStmeGyiFk/H+/2GN57gOhbhPcF4qwP2JX0gWQkZYIKB6nnm0FeTxhIFHGvVAjjx LZxKuWnueRRKhv82EI5oZQYSkOLSgf/qJZY6SHyh/W0PxtEJBjukViVzVw8KWlZepJ9E CZzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701632026; x=1702236826; 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=NbCVZUZWRPuqODDp3Z8qmjnrbZPazZZzGPA5ZDraoqY=; b=h4z0gDRL3bUNtp9m/8Tq8EH9dBdJMHUAdVhYypBSKqDel4x9aClv/BgRJQ2sBPVzin dHpDMH/xxcV/H6MVWvfmfF9nTNdFyEeo7LC9xCu6NUFrwbu+NYi5GbIc7hkJmg8qU3Fu zmYW33bugsWAQ/iLzK0wjvzniZRVwDe37HlLBko06utN6FPLP5+png4wCGIjaU7n9r5Y ZmX0+3Spocibq2KTk+7jNtyfDRN8G9Xt14orZllNyYEatHu2fIdlxMGOmkYNQ+jfidLf RZyFtJJjxvkdN8ZJIiW49GhB6GC84gKwdPhctOwBkOIRjjGnQWAap/IS1YWMLpFVfz9L aRWg== X-Gm-Message-State: AOJu0YyHQ6HGeWKFYAT2Y2zAOJNa2kX8QkTF0w6dd9w0wlR4/BgDVCJd aL9A83XvYT1/xDmKhzKZ+gFHHg+AsunefA== X-Google-Smtp-Source: AGHT+IGu0APP9u8wu69W2xKOsAN5cuKpTM7AUbqner4I5ZDEE4Zj4TzmSznLt47vQLMdxzliHcTAdQ== X-Received: by 2002:a25:bc90:0:b0:db5:4b47:24ec with SMTP id e16-20020a25bc90000000b00db54b4724ecmr1236954ybk.36.1701632026299; Sun, 03 Dec 2023 11:33:46 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:cb98:c3e:57c:8191]) by smtp.gmail.com with ESMTPSA id g188-20020a0df6c5000000b005a7daa09f43sm2758328ywf.125.2023.12.03.11.33.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 11:33:45 -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 , Bart Van Assche , Sergey Shtylyov Subject: [PATCH v2 21/35] sfc: switch to using atomic find_bit() API where appropriate Date: Sun, 3 Dec 2023 11:32:53 -0800 Message-Id: <20231203193307.542794-20-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231203193307.542794-1-yury.norov@gmail.com> References: <20231203192422.539300-1-yury.norov@gmail.com> <20231203193307.542794-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 Sun Dec 3 19:32:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13477466 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="INmutiGk" Received: from mail-yb1-xb33.google.com (mail-yb1-xb33.google.com [IPv6:2607:f8b0:4864:20::b33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5884919F; Sun, 3 Dec 2023 11:33:56 -0800 (PST) Received: by mail-yb1-xb33.google.com with SMTP id 3f1490d57ef6-daf4f0e3a0fso1923328276.1; Sun, 03 Dec 2023 11:33:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701632034; x=1702236834; 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=umylsjeSPs0cDBz7+FTUGH2Vn0LO0b26GddccWPu0Jc=; b=INmutiGknFZp4otivmEjEN6U5i9K+DYuNAAwT4RR6E6MHxetNGsWEjpz4PFZZ3NewE XoKmhzornVPQikoYdYEKbY0/ENZMcQNcbTSwLpRGFI+8ruV0Xm9BKJ64Jqxn27jK5u4v F4MphdmtdPwA6l/hAJcLIgbq15egqT9GYh6fAJ9uteezJ3DFwfqJ2TKc3d0XCR5IFTQH eSp8g1BkM4R+thZ3DYoDIsO+5JEY8faCXPyWKqK+yjzdenQdE5P+JPtH/bJAcOib480v 1CKY9k6RMfd/HfancmSlu0slSrXlX7zyKSu+vuigYABNaVGhOPLTw21ZcPCy0tiBj7WD LUzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701632034; x=1702236834; 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=umylsjeSPs0cDBz7+FTUGH2Vn0LO0b26GddccWPu0Jc=; b=UTFgThxl5cLW5H480WHyvTltiuI1rEDZJj+XSsd5lmaSlVM/5wwZ6iFOuH5SYqVzp0 SH43b3k9NVnziXWgEuWqh/QzAsklti0sV+HUFxOjE4Z5pi2jzTyafEfxyjQejwOUvSe7 iPjBJICEq+W+nduJmCV2wIPMaunAr0QFEOkpwLjbOa66eWJOq1o51+43Bsh65vYnMjqb l6Ap2nZuWxvh8QlzMwj0WXrFuzTYdcPsRYPcnUQvNjJ591NJ27CnILxpCE7hqV/J4g4A i7148fVLvS8fij6tm/Cj9JxvruXv56FnOsJOIFT6SO3JWbTOLBCngqQ2tcX170rVmJ7z pIdA== X-Gm-Message-State: AOJu0YzgsN/84LRH1P435owWM29qOW8iSSsXH4+rY11skcq8wOtoerdg lykASl1wZX1Sqs0mTG5NB/p1Z6qbL9OCkA== X-Google-Smtp-Source: AGHT+IEMrAskXkIWksgXiWbXkBl3jPfPd1x1T+uOqGjr26YyA+tnyIwo24cYyzJVLZxKOZWy5dfEjA== X-Received: by 2002:a5b:28c:0:b0:d9b:87f3:54f9 with SMTP id x12-20020a5b028c000000b00d9b87f354f9mr2129725ybl.28.1701632034561; Sun, 03 Dec 2023 11:33:54 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:cb98:c3e:57c:8191]) by smtp.gmail.com with ESMTPSA id o145-20020a257397000000b00d9caecd5c86sm1810336ybc.62.2023.12.03.11.33.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 11:33:53 -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 , Bart Van Assche , Sergey Shtylyov Subject: [PATCH v2 26/35] mISDN: optimize get_free_devid() Date: Sun, 3 Dec 2023 11:32:58 -0800 Message-Id: <20231203193307.542794-25-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231203193307.542794-1-yury.norov@gmail.com> References: <20231203192422.539300-1-yury.norov@gmail.com> <20231203193307.542794-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 Sun Dec 3 19:33: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: 13477465 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="JgytcY7N" 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 3A556113; Sun, 3 Dec 2023 11:34:00 -0800 (PST) Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-5cece20f006so44070457b3.3; Sun, 03 Dec 2023 11:34:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701632039; x=1702236839; 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=oOA21j87mR+yiywFqhw/n2ogDgEt85D4G/d7gO/inIA=; b=JgytcY7N94v8jdinYmONzMtSa4aq07zgEq2N2MywhkQAtb67A7JzB67D86goKcEWMW 9epDoR4YQTtvbPmTodJynrjJts199/nCIhuOQk0ip8ZJGejsCnj23v2+GPrNoyFNeQLO RmQHuRTF5E0xugwA8Cty2QcvznEqIxqNArMweIaTCirV+w0m/H0NNsHItRDrPTnVuEvE k/mIe8bk69cxOz5qEggKAo7ryY38Ivb1ShUkHw9jxfnEEBb5jNuVY0VapMhmGMEJsKbp BrpNOpJFHV545SR9rTvV1Md/vSDziEXDLO1eKoWQkpCwD4MDA5uOJBDJcRGyw675YnWb xGSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701632039; x=1702236839; 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=oOA21j87mR+yiywFqhw/n2ogDgEt85D4G/d7gO/inIA=; b=WO8Vu98n1OGwzgAimE/o0QuC9FmRN/9z53Cx5Fy24wetDMMGpoOeQZSNAB4ytrMLJm txHJ6fDhPB36Yw/ItZCvnD8/4iZ9ApoqQXAiwvqmv7v7OXcc0jPmPBq3Ag04njmvfqpJ UJGy61wGUJ+V5E4r/vCEye0u5PkyNADhjRsN/a9UIh/RBLc/W1EiHW18i72Gi1gi94HU P7gq/FRz8kVuomtpniQpbDrWOIl9SEc0+AcHlIc4CjzM7yW9PlwT8noPnic29omxLi8i 0dOYQX3ARF0+3ikXOSEO4YAVf/6mrGxenSAz7QmuJpla6iW1jcZDTQk3GQbboYuhOLCb OvCA== X-Gm-Message-State: AOJu0Yxxlv/KsbJOStqB0Io9YY/EMlJ/m6UMU2anXU/N2gZhn+ZdAE3b AcVhMWC8u5SW1tCsYvZaY9mSEW8husdDJA== X-Google-Smtp-Source: AGHT+IHXy1WAEEEpXL8d3Qiwz0WaUvvRd1DJhAPAt9NZCAbQTeYlZnMbDBTKqf04Wx3t8kWOvaFN/w== X-Received: by 2002:a0d:ebd4:0:b0:5d7:1940:f3ef with SMTP id u203-20020a0debd4000000b005d71940f3efmr2486245ywe.87.1701632038986; Sun, 03 Dec 2023 11:33:58 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:cb98:c3e:57c:8191]) by smtp.gmail.com with ESMTPSA id w20-20020a81a214000000b005d40a826831sm2113106ywg.115.2023.12.03.11.33.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 11:33:57 -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 , Bart Van Assche , Sergey Shtylyov Subject: [PATCH v2 28/35] ethernet: rocker: optimize ofdpa_port_internal_vlan_id_get() Date: Sun, 3 Dec 2023 11:33:00 -0800 Message-Id: <20231203193307.542794-27-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231203193307.542794-1-yury.norov@gmail.com> References: <20231203192422.539300-1-yury.norov@gmail.com> <20231203193307.542794-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 Sun Dec 3 19:33:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13477469 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="ikQOY9tw" Received: from mail-yw1-x112c.google.com (mail-yw1-x112c.google.com [IPv6:2607:f8b0:4864:20::112c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 341ED2107; Sun, 3 Dec 2023 11:34:04 -0800 (PST) Received: by mail-yw1-x112c.google.com with SMTP id 00721157ae682-5d77a1163faso7155697b3.0; Sun, 03 Dec 2023 11:34:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701632042; x=1702236842; 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=lLIpPFsand/i1xzhRvuWZWdTEGryuaeNcdCEZ2uAMCg=; b=ikQOY9twYk8DY0FzEdHM4506y+8fZlMZyC1Ldaqqq+OsuSQAmVYtUEoNxWmX2UXLHo iipYoEzTvjMmaeHKonchgcfqdvdDcODXjou//SrvCiqS4Vmk6xjPXycUOmPX60H9laJH yRGs/qcycmPdHvHmVSeUPFyW8Dtrl5jHuOXa28xcNR5S9NtDx070z75wX4nqcNA6kVLP X1WzRUFvB8OKkO6UvFM13L11I/6cFHMadx6XnCVEL1je1PzEs2+UxT7qYEP42Ii+HLTD f7MP6YLlLM5y6d0GfqqmB49uEV/54aX02fXlUM4rvc2q4Q0PchPWF1xzXNJeu3O1L5K7 ooLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701632042; x=1702236842; 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=lLIpPFsand/i1xzhRvuWZWdTEGryuaeNcdCEZ2uAMCg=; b=Ei5Huy7+YVSf5u8ZuegITtmd7xSctsmYSKCUftgR0WS9jZRFzRsopnLjBEo1hPTNli zheWjAJx6j6S10C8bp0W6+zI3YSyJEMSo8IYYV66hdH45lg0abRZszt3U9k/B8IrbSUs ZsLY6yDU1xoeV7C53jd0lBYYpuZXFWp873Ae1LCmUgnE0FGh5AQ4GpKDFsHrLxjXvud4 +rm2WyNAtgTIDZa21mavUih9p2fGJWgJXhR/wwPIrNtVoPGIxQFBOxbqNlEOd0GNv72A 9fgGNtKpYFyyD9n/UpA/+L15x7XvOLNBVQyARq2/GPiVyHX7bpmr7Ga6Az1sGNKw0imP NWyQ== X-Gm-Message-State: AOJu0YwP8kzIy48FyeBQumiNDqe3jM6gEFSjQfXaU5m7wsL50BpWDRvJ S0ON3FxW3Dr+/1RMpQY7NTmVNU2opZiZdQ== X-Google-Smtp-Source: AGHT+IF7TlbMvqX4zBK0qN69lty4JT5J+hOZOMnrAIhG2aaSguNl8zsIA2Kc3TBbQ2Xbvw2rXB+lGQ== X-Received: by 2002:a81:4320:0:b0:5d6:d420:cb29 with SMTP id q32-20020a814320000000b005d6d420cb29mr1604031ywa.14.1701632042389; Sun, 03 Dec 2023 11:34:02 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:cb98:c3e:57c:8191]) by smtp.gmail.com with ESMTPSA id c68-20020a0dc147000000b005d6f34893dfsm1612853ywd.135.2023.12.03.11.34.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 11:34:02 -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 , Bart Van Assche , Sergey Shtylyov Subject: [PATCH v2 30/35] bluetooth: optimize cmtp_alloc_block_id() Date: Sun, 3 Dec 2023 11:33:02 -0800 Message-Id: <20231203193307.542794-29-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231203193307.542794-1-yury.norov@gmail.com> References: <20231203192422.539300-1-yury.norov@gmail.com> <20231203193307.542794-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 Sun Dec 3 19:33:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 13477467 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="S8FjXbL+" 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 9F5552116; Sun, 3 Dec 2023 11:34:05 -0800 (PST) Received: by mail-yb1-xb34.google.com with SMTP id 3f1490d57ef6-db8892a5f96so778827276.2; Sun, 03 Dec 2023 11:34:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701632044; x=1702236844; 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=tow+85T+lc+N5QthCRRY7+xksWqAIO8q8vX1kWlFmwA=; b=S8FjXbL+Om07tTWypyRabwgvKQMEr/uxqw3jaqPqfXxvRJasTDSmpGGHFPSbFMiH7V fQBZphDsUWDU+5IQ+a3DtQZcV/UoXX3rXrwSX8HK7A9Dw3nI3VSzBFWivQnH+IzJ3bCn G1CNIAO5gsQ18SvVo34/e1L8lumlzYAS9IlobGLPi2LyRKl21lGv/GrpxiOxNSyNfZVA uJ/7ec2UYYzfA63vLqDjcmqw2+j7Rj2ZKH/JiwCjExh+QYnEZTV6Wx6//6qA6tmjxS5K A8y10wN1cHbYX4fH+IUMPMylobCEZN9swQ6tnKTf70i0d6tNaIS3y1mAJPFv/X5z5euj W25w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701632044; x=1702236844; 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=tow+85T+lc+N5QthCRRY7+xksWqAIO8q8vX1kWlFmwA=; b=lpyO5K6jHutrCWknsNUU2o3mO1Qh5WInAUtBlxFo+BQPcPJVKRqGgA6FYvBnaaOcaK FJN2FDUzN/TgcUr6U4864xmSV7b+ablM2J1XqNeaRWgpp2HCkkNHxeN7dZPZdqMWUzSz MtkTMKdMKRZfvwkt7ESQJj3op7Fw+aRkh62lF1nlvoZyngMfy+GlBni2IYfY3iQJpXzy 4IYXHM3VWmF6N7a6f81o9UmKPLhLPJPbteswMtsdi5xiqsLelTsXYv569gOe5hlh7DC7 C22vDXomC9ZwdudOtUkI53Ubw0MbqfL2UDDdhHkM9noo5xdi5WFGFtn3VS0+VuJ33x6W B2zQ== X-Gm-Message-State: AOJu0Yy1Y/q/wyLQb+Mte8EoOI8GQlh9194IAqoww4XDtOYiZioNuayx /fzQAr15VTjx50Nr77cDLOrlKBnchBt+9A== X-Google-Smtp-Source: AGHT+IFdVY+nDvHApuybbKRgPwqo30yRyljr/trWB68rXRo3Ez+hOUZ7Bb+kBQ88sAzhLkZwEbNRpQ== X-Received: by 2002:a25:457:0:b0:db7:dacf:6205 with SMTP id 84-20020a250457000000b00db7dacf6205mr1739115ybe.87.1701632044112; Sun, 03 Dec 2023 11:34:04 -0800 (PST) Received: from localhost ([2601:344:8301:57f0:cb98:c3e:57c:8191]) by smtp.gmail.com with ESMTPSA id bt13-20020a056902136d00b00d72176bdc5csm1759016ybb.40.2023.12.03.11.34.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 11:34:03 -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 , Bart Van Assche , Sergey Shtylyov , Alexandra Winter Subject: [PATCH v2 31/35] net: smc: use find_and_set_bit() in smc_wr_tx_get_free_slot_index() Date: Sun, 3 Dec 2023 11:33:03 -0800 Message-Id: <20231203193307.542794-30-yury.norov@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231203193307.542794-1-yury.norov@gmail.com> References: <20231203192422.539300-1-yury.norov@gmail.com> <20231203193307.542794-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. Use it, and make the whole function a simple almost one-liner. While here, drop explicit initialization of *idx, because it's already initialized by the caller in case of ENOLINK, or set properly with ->wr_tx_mask, if nothing is found, in case of EBUSY. CC: Tony Lu CC: Alexandra Winter Signed-off-by: Yury Norov Reviewed-by: Alexandra Winter --- 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; } /**