All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yi Sun <yi.sun@unisoc.com>
To: <yi.sun@unisoc.com>, <yury.norov@gmail.com>, <akpm@linux-foundation.org>
Cc: <mina86@mina86.com>, <akinobu.mita@gmail.com>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH 1/2] lib: bitmap: add find_last_bit_range() and _find_last_bit_range()
Date: Tue, 12 May 2026 12:06:58 +0800	[thread overview]
Message-ID: <20260512040659.2992142-2-yi.sun@unisoc.com> (raw)
In-Reply-To: <20260512040659.2992142-1-yi.sun@unisoc.com>

In some scenarios, it's not desirable to keep searching through the
beginning of the bitmap, but rather to search within a specific part.
The newly added function can accomplish this quickly.

Signed-off-by: Yi Sun <yi.sun@unisoc.com>
---
 include/linux/find.h | 35 +++++++++++++++++++++++++++++++++++
 lib/find_bit.c       | 30 ++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/include/linux/find.h b/include/linux/find.h
index 6c2be8ca615d..7126b0fffe0f 100644
--- a/include/linux/find.h
+++ b/include/linux/find.h
@@ -33,6 +33,8 @@ unsigned long _find_first_and_and_bit(const unsigned long *addr1, const unsigned
 				      const unsigned long *addr3, unsigned long size);
 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);
+extern unsigned long _find_last_bit_range(const unsigned long *addr, unsigned long size,
+					unsigned long offset);
 
 #ifdef __BIG_ENDIAN
 unsigned long _find_first_zero_bit_le(const unsigned long *addr, unsigned long size);
@@ -413,6 +415,39 @@ unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
 }
 #endif
 
+#ifndef find_last_bit_range
+/**
+ * find_last_bit_range - find the last set bit in a memory region
+ * @addr: The address to base the search on
+ * @size: The bitmap size in bits
+ * @offset: The bit number to start searching at
+ *
+ * Compared to the find_last_bit(),
+ * find_last_bit_range() has an additional parameter @offset,
+ * so it can search within a specific range of the bitmap,
+ * just like the find_next_bit().
+ *
+ * Returns the bit number of the last set bit, or size.
+ */
+static __always_inline
+unsigned long find_last_bit_range(const unsigned long *addr, unsigned long size,
+				unsigned long offset)
+{
+	if (small_const_nbits(size)) {
+		unsigned long val;
+
+		if (unlikely(offset >= size))
+			return size;
+
+		val = *addr & GENMASK(size - 1, offset);
+
+		return val ? __fls(val) : size;
+	}
+
+	return _find_last_bit_range(addr, size, offset);
+}
+#endif
+
 /**
  * find_next_and_bit_wrap - find the next set bit in both memory regions
  * @addr1: The first address to base the search on
diff --git a/lib/find_bit.c b/lib/find_bit.c
index 5ac52dfce730..bedc85053cea 100644
--- a/lib/find_bit.c
+++ b/lib/find_bit.c
@@ -237,6 +237,36 @@ unsigned long _find_last_bit(const unsigned long *addr, unsigned long size)
 EXPORT_SYMBOL(_find_last_bit);
 #endif
 
+#ifndef find_last_bit_range
+unsigned long _find_last_bit_range(const unsigned long *addr, unsigned long size,
+				unsigned long offset)
+{
+	unsigned long val, idx, start_idx;
+
+	if (unlikely(offset >= size))
+		return size;
+
+	val = BITMAP_LAST_WORD_MASK(size);
+	idx = (size - 1) / BITS_PER_LONG;
+	start_idx = offset / BITS_PER_LONG;
+
+	do {
+		val &= addr[idx];
+
+		if (idx == start_idx)
+			val &= BITMAP_FIRST_WORD_MASK(offset);
+
+		if (val)
+			return idx * BITS_PER_LONG + __fls(val);
+
+		val = ~0UL;
+	} while (idx-- > start_idx);
+
+	return size;
+}
+EXPORT_SYMBOL(_find_last_bit_range);
+#endif
+
 unsigned long find_next_clump8(unsigned long *clump, const unsigned long *addr,
 			       unsigned long size, unsigned long offset)
 {
-- 
2.34.1


  reply	other threads:[~2026-05-12  4:12 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-12  4:06 [PATCH 0/2] Improve the performance of bitmap_find_next_zero_area_off() Yi Sun
2026-05-12  4:06 ` Yi Sun [this message]
2026-05-12 11:31   ` [PATCH 1/2] lib: bitmap: add find_last_bit_range() and _find_last_bit_range() Michał Nazarewicz
2026-05-12 16:46   ` Yury Norov
2026-05-12  4:06 ` [PATCH 2/2] lib: bitmap: reduce the number of goto again in bitmap_find_next_zero_area_off() Yi Sun
2026-05-12 11:32   ` Michał Nazarewicz
2026-05-12 16:51   ` Yury Norov
2026-05-14  3:02     ` 答复: " 孙毅 (Yi Sun)
2026-05-12 16:34 ` [PATCH 0/2] Improve the performance of bitmap_find_next_zero_area_off() Yury Norov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260512040659.2992142-2-yi.sun@unisoc.com \
    --to=yi.sun@unisoc.com \
    --cc=akinobu.mita@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mina86@mina86.com \
    --cc=yury.norov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.