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 |
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 --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;
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(-)