Commit da6d8dbb authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Sasha Levin

dm bufio: make the parameter "retain_bytes" unsigned long

[ Upstream commit 13840d38 ]

Change the type of the parameter "retain_bytes" from unsigned to
unsigned long, so that on 64-bit machines the user can set more than
4GiB of data to be retained.

Also, change the type of the variable "count" in the function
"__evict_old_buffers" to unsigned long.  The assignment
"count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY];"
could result in unsigned long to unsigned overflow and that could result
in buffers not being freed when they should.

While at it, avoid division in get_retain_buffers().  Division is slow,
we can change it to shift because we have precalculated the log2 of
block size.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Signed-off-by: default avatarSasha Levin <alexander.levin@verizon.com>
parent b9805634
...@@ -222,7 +222,7 @@ static DEFINE_SPINLOCK(param_spinlock); ...@@ -222,7 +222,7 @@ static DEFINE_SPINLOCK(param_spinlock);
* Buffers are freed after this timeout * Buffers are freed after this timeout
*/ */
static unsigned dm_bufio_max_age = DM_BUFIO_DEFAULT_AGE_SECS; static unsigned dm_bufio_max_age = DM_BUFIO_DEFAULT_AGE_SECS;
static unsigned dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES; static unsigned long dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES;
static unsigned long dm_bufio_peak_allocated; static unsigned long dm_bufio_peak_allocated;
static unsigned long dm_bufio_allocated_kmem_cache; static unsigned long dm_bufio_allocated_kmem_cache;
...@@ -1508,10 +1508,10 @@ static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp) ...@@ -1508,10 +1508,10 @@ static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp)
return true; return true;
} }
static unsigned get_retain_buffers(struct dm_bufio_client *c) static unsigned long get_retain_buffers(struct dm_bufio_client *c)
{ {
unsigned retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes); unsigned long retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
return retain_bytes / c->block_size; return retain_bytes >> (c->sectors_per_block_bits + SECTOR_SHIFT);
} }
static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan, static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
...@@ -1521,7 +1521,7 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan, ...@@ -1521,7 +1521,7 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
struct dm_buffer *b, *tmp; struct dm_buffer *b, *tmp;
unsigned long freed = 0; unsigned long freed = 0;
unsigned long count = nr_to_scan; unsigned long count = nr_to_scan;
unsigned retain_target = get_retain_buffers(c); unsigned long retain_target = get_retain_buffers(c);
for (l = 0; l < LIST_SIZE; l++) { for (l = 0; l < LIST_SIZE; l++) {
list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) { list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) {
...@@ -1747,8 +1747,8 @@ static bool older_than(struct dm_buffer *b, unsigned long age_hz) ...@@ -1747,8 +1747,8 @@ static bool older_than(struct dm_buffer *b, unsigned long age_hz)
static void __evict_old_buffers(struct dm_bufio_client *c, unsigned long age_hz) static void __evict_old_buffers(struct dm_bufio_client *c, unsigned long age_hz)
{ {
struct dm_buffer *b, *tmp; struct dm_buffer *b, *tmp;
unsigned retain_target = get_retain_buffers(c); unsigned long retain_target = get_retain_buffers(c);
unsigned count; unsigned long count;
LIST_HEAD(write_list); LIST_HEAD(write_list);
dm_bufio_lock(c); dm_bufio_lock(c);
...@@ -1913,7 +1913,7 @@ MODULE_PARM_DESC(max_cache_size_bytes, "Size of metadata cache"); ...@@ -1913,7 +1913,7 @@ MODULE_PARM_DESC(max_cache_size_bytes, "Size of metadata cache");
module_param_named(max_age_seconds, dm_bufio_max_age, uint, S_IRUGO | S_IWUSR); module_param_named(max_age_seconds, dm_bufio_max_age, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(max_age_seconds, "Max age of a buffer in seconds"); MODULE_PARM_DESC(max_age_seconds, "Max age of a buffer in seconds");
module_param_named(retain_bytes, dm_bufio_retain_bytes, uint, S_IRUGO | S_IWUSR); module_param_named(retain_bytes, dm_bufio_retain_bytes, ulong, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(retain_bytes, "Try to keep at least this many bytes cached in memory"); MODULE_PARM_DESC(retain_bytes, "Try to keep at least this many bytes cached in memory");
module_param_named(peak_allocated_bytes, dm_bufio_peak_allocated, ulong, S_IRUGO | S_IWUSR); module_param_named(peak_allocated_bytes, dm_bufio_peak_allocated, ulong, S_IRUGO | S_IWUSR);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment