From: Ming-Hung Tsai <mtsai@xxxxxxxxxx> 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@xxxxxxxxxx> Fixes: f494a9c6b1b6 ("dm cache: cache shrinking support") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Mikulas Patocka <mpatocka@xxxxxxxxxx> Acked-by: Joe Thornber <thornber@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/md/dm-cache-target.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -3001,14 +3001,14 @@ static bool can_resize(struct cache *cac /* * 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; Patches currently in stable-queue which might be from mtsai@xxxxxxxxxx are queue-4.19/dm-cache-correct-the-number-of-origin-blocks-to-match-the-target-length.patch queue-4.19/dm-cache-fix-potential-out-of-bounds-access-on-the-first-resume.patch queue-4.19/dm-cache-optimize-dirty-bit-checking-with-find_next_bit-when-resizing.patch queue-4.19/dm-cache-fix-out-of-bounds-access-to-the-dirty-bitset-when-resizing.patch