In the original dm-bufio, setting dm_bufio_cache_size to 0 meant to set the default value. However, when the code was refactored in the commit 450e8dee51aa, the meaning of 0 is inconsistent, at some places, we just read the variable dm_bufio_cache_size without testing it to zero.
This commit cleans up the zero handling, all reads of dm_bufio_cache_size go through the function dm_budio_get_cache_size() and this function tests the variable for zero and sets the default cache size in this case. Signed-off-by: Mikulas Patocka <[email protected]> Assisted-by: Claude:claude-opus-5 --- drivers/md/dm-bufio.c | 59 ++++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 40 deletions(-) Index: linux-2.6/drivers/md/dm-bufio.c =================================================================== --- linux-2.6.orig/drivers/md/dm-bufio.c +++ linux-2.6/drivers/md/dm-bufio.c @@ -1044,12 +1044,6 @@ static unsigned long dm_bufio_default_ca */ static unsigned long dm_bufio_cache_size; -/* - * A copy of dm_bufio_cache_size because dm_bufio_cache_size can change - * at any time. If it disagrees, the user has changed cache size. - */ -static unsigned long dm_bufio_cache_size_latch; - static DEFINE_SPINLOCK(global_spinlock); static unsigned int dm_bufio_max_age; /* No longer does anything */ @@ -1076,7 +1070,7 @@ static int dm_bufio_client_count; static LIST_HEAD(dm_bufio_all_clients); /* - * This mutex protects dm_bufio_cache_size_latch and dm_bufio_client_count + * This mutex protects dm_bufio_client_count */ static DEFINE_MUTEX(dm_bufio_clients_lock); @@ -1093,6 +1087,17 @@ static void buffer_record_stack(struct d /*----------------------------------------------------------------*/ +static unsigned long dm_budio_get_cache_size(void) +{ + unsigned long s = READ_ONCE(dm_bufio_cache_size); + if (unlikely(!s)) { + unsigned long d = dm_bufio_default_cache_size; + (void)cmpxchg(&dm_bufio_cache_size, 0, d); + s = d; + } + return s; +} + static void adjust_total_allocated(struct dm_buffer *b, bool unlink) { unsigned char data_mode; @@ -1120,7 +1125,7 @@ static void adjust_total_allocated(struc dm_bufio_peak_allocated = dm_bufio_current_allocated; if (!unlink) { - if (dm_bufio_current_allocated > dm_bufio_cache_size) + if (dm_bufio_current_allocated > dm_budio_get_cache_size()) queue_work(dm_bufio_wq, &dm_bufio_replacement_work); } @@ -1128,28 +1133,6 @@ static void adjust_total_allocated(struc } /* - * Change the number of clients and recalculate per-client limit. - */ -static void __cache_size_refresh(void) -{ - if (WARN_ON(!mutex_is_locked(&dm_bufio_clients_lock))) - return; - if (WARN_ON(dm_bufio_client_count < 0)) - return; - - dm_bufio_cache_size_latch = READ_ONCE(dm_bufio_cache_size); - - /* - * Use default if set to 0 and report the actual cache size used. - */ - if (!dm_bufio_cache_size_latch) { - (void)cmpxchg(&dm_bufio_cache_size, 0, - dm_bufio_default_cache_size); - dm_bufio_cache_size_latch = dm_bufio_default_cache_size; - } -} - -/* * Allocating buffer data. * * Small buffers are allocated with kmem_cache, to use space optimally. @@ -1618,7 +1601,7 @@ static struct dm_buffer *__alloc_buffer_ * be allocated. */ while (1) { - if (dm_bufio_cache_size_latch != 1) { + if (dm_budio_get_cache_size() != 1) { b = alloc_buffer(c, GFP_NOWAIT | __GFP_NORETRY | __GFP_NOMEMALLOC); if (b) return b; @@ -1627,7 +1610,7 @@ static struct dm_buffer *__alloc_buffer_ if (nf == NF_PREFETCH) return NULL; - if (dm_bufio_cache_size_latch != 1 && !tried_noio_alloc) { + if (dm_budio_get_cache_size() != 1 && !tried_noio_alloc) { dm_bufio_unlock(c); b = alloc_buffer(c, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); dm_bufio_lock(c); @@ -2616,7 +2599,6 @@ struct dm_bufio_client *dm_bufio_client_ mutex_lock(&dm_bufio_clients_lock); dm_bufio_client_count++; list_add(&c->client_list, &dm_bufio_all_clients); - __cache_size_refresh(); mutex_unlock(&dm_bufio_clients_lock); return c; @@ -2658,7 +2640,6 @@ void dm_bufio_client_destroy(struct dm_b list_del(&c->client_list); dm_bufio_client_count--; - __cache_size_refresh(); mutex_unlock(&dm_bufio_clients_lock); @@ -2827,8 +2808,8 @@ static void check_watermarks(void) static void evict_old(void) { - unsigned long threshold = dm_bufio_cache_size - - dm_bufio_cache_size / DM_BUFIO_LOW_WATERMARK_RATIO; + unsigned long cs = dm_budio_get_cache_size(); + unsigned long threshold = cs - cs / DM_BUFIO_LOW_WATERMARK_RATIO; int unproductive = 0; mutex_lock(&dm_bufio_clients_lock); @@ -2889,10 +2870,8 @@ static int __init dm_bufio_init(void) #endif dm_bufio_default_cache_size = mem; - - mutex_lock(&dm_bufio_clients_lock); - __cache_size_refresh(); - mutex_unlock(&dm_bufio_clients_lock); + if (!dm_bufio_cache_size) + dm_bufio_cache_size = mem; dm_bufio_wq = alloc_workqueue("dm_bufio_cache", WQ_MEM_RECLAIM | WQ_PERCPU, 0);
