diff mbox series

[4/5] dm cache: optimize dirty bit checking with find_next_bit when resizing

Message ID 20241022071339.778721-1-mtsai@redhat.com (mailing list archive)
State Accepted, archived
Delegated to: Mikulas Patocka
Headers show
Series dm cache: fix OOB and error handling in cache creation and resizing | expand

Commit Message

Ming-Hung Tsai Oct. 22, 2024, 7:13 a.m. UTC
When shrinking the fast device, dm-cache iteratively searches for a
dirty bit among the cache blocks to be dropped, which is less efficient.
Use find_next_bit instead, as it is twice as fast as the iterative
approach with test_bit.

Signed-off-by: Ming-Hung Tsai <mtsai@redhat.com>
---
 drivers/md/dm-cache-target.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

Comments

Joe Thornber Oct. 22, 2024, 7:31 a.m. UTC | #1
ack

On Tue, Oct 22, 2024 at 8:13 AM Ming-Hung Tsai <mtsai@redhat.com> wrote:
>
> When shrinking the fast device, dm-cache iteratively searches for a
> dirty bit among the cache blocks to be dropped, which is less efficient.
> Use find_next_bit instead, as it is twice as fast as the iterative
> approach with test_bit.
>
> Signed-off-by: Ming-Hung Tsai <mtsai@redhat.com>
> ---
>  drivers/md/dm-cache-target.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
> index 1fcd8c5c220e..fa8ef2c32af8 100644
> --- a/drivers/md/dm-cache-target.c
> +++ b/drivers/md/dm-cache-target.c
> @@ -2911,14 +2911,14 @@ static bool can_resize(struct cache *cache, dm_cblock_t new_size)
>         /*
>          * We can't drop a dirty block when shrinking the cache.
>          */
> -       while (from_cblock(new_size) < from_cblock(cache->cache_size)) {
> -               if (is_dirty(cache, new_size)) {
> -                       DMERR("%s: unable to shrink cache; cache block %llu is dirty",
> -                             cache_device_name(cache),
> -                             (unsigned long long) from_cblock(new_size));
> -                       return false;
> -               }
> -               new_size = to_cblock(from_cblock(new_size) + 1);
> +       new_size = to_cblock(find_next_bit(cache->dirty_bitset,
> +                                          from_cblock(cache->cache_size),
> +                                          from_cblock(new_size)));
> +       if (new_size != cache->cache_size) {
> +               DMERR("%s: unable to shrink cache; cache block %llu is dirty",
> +                     cache_device_name(cache),
> +                     (unsigned long long) from_cblock(new_size));
> +               return false;
>         }
>
>         return true;
> --
> 2.47.0
>
diff mbox series

Patch

diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 1fcd8c5c220e..fa8ef2c32af8 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -2911,14 +2911,14 @@  static bool can_resize(struct cache *cache, dm_cblock_t new_size)
 	/*
 	 * We can't drop a dirty block when shrinking the cache.
 	 */
-	while (from_cblock(new_size) < from_cblock(cache->cache_size)) {
-		if (is_dirty(cache, new_size)) {
-			DMERR("%s: unable to shrink cache; cache block %llu is dirty",
-			      cache_device_name(cache),
-			      (unsigned long long) from_cblock(new_size));
-			return false;
-		}
-		new_size = to_cblock(from_cblock(new_size) + 1);
+	new_size = to_cblock(find_next_bit(cache->dirty_bitset,
+					   from_cblock(cache->cache_size),
+					   from_cblock(new_size)));
+	if (new_size != cache->cache_size) {
+		DMERR("%s: unable to shrink cache; cache block %llu is dirty",
+		      cache_device_name(cache),
+		      (unsigned long long) from_cblock(new_size));
+		return false;
 	}
 
 	return true;