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

On Tue, May 12 2026, Yi Sun wrote:
> 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>

Acked-by: Michał Nazarewicz <mina86@mina86.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)

This should be called find_last_bit_off instead.  `_range` suffix, to me
at least, implies that the order of arguments is (addr, offset, size).
`_off` is also the suffix used by `bitmap_find_next_zero_area_off` name.

> +{
> +	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);

Perhaps:

```
	val = BITMAP_LAST_WORD_MASK(size) & addr[idx];
	while (!val && idx > start_idx)
		val = addr[--idx];
	if (idx == start_idx)
		val &= BITMAP_FIRST_WORD_MASK(offset);
	return val ? idx * BITS_PER_LONG + __fls(val) : size;
```

This moves the `idx == start_idx` condition outside of the loop so that
it’s not checked on each iteration.  It also removes the need for `val =
~0UL` from the loop again simplifying its body.

> +
> +	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)
>  {

-- 
Best regards
ミハウ “𝓶𝓲𝓷𝓪86” ナザレヴィツ
«If at first you don’t succeed, give up skydiving»

  reply	other threads:[~2026-05-12 11:31 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 ` [PATCH 1/2] lib: bitmap: add find_last_bit_range() and _find_last_bit_range() Yi Sun
2026-05-12 11:31   ` Michał Nazarewicz [this message]
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=j5sumb+en9pkhmsincnmn+6a@mina86.com \
    --to=mina86@mina86.com \
    --cc=akinobu.mita@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=yi.sun@unisoc.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.