diff options
author | Ming-Hung Tsai <mtsai@redhat.com> | 2024-10-22 10:13:39 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-11-14 15:19:37 +0300 |
commit | 53421c3c0ee04bd2bf7080d2ac157a419cf89c91 (patch) | |
tree | 10bc979b525ad57b8117d89e662b49adb2fcda9d | |
parent | e57648ce325fa405fe6bbd0e6a618ced7c301a2d (diff) | |
download | linux-53421c3c0ee04bd2bf7080d2ac157a419cf89c91.tar.xz |
dm cache: optimize dirty bit checking with find_next_bit when resizing
commit f484697e619a83ecc370443a34746379ad99d204 upstream.
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>
Fixes: f494a9c6b1b6 ("dm cache: cache shrinking support")
Cc: stable@vger.kernel.org
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Acked-by: Joe Thornber <thornber@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/md/dm-cache-target.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index fd3000bd6146..2923e292eb72 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2915,14 +2915,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; |