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

dm bufio: check new buffer allocation watermark every 30 seconds

[ Upstream commit 390020ad ]

dm-bufio checks a watermark when it allocates a new buffer in
__bufio_new().  However, it doesn't check the watermark when the user
changes /sys/module/dm_bufio/parameters/max_cache_size_bytes.

This may result in a problem - if the watermark is high enough so that
all possible buffers are allocated and if the user lowers the value of
"max_cache_size_bytes", the watermark will never be checked against the
new value because no new buffer would be allocated.

To fix this, change __evict_old_buffers() so that it checks the
watermark.  __evict_old_buffers() is called every 30 seconds, so if the
user reduces "max_cache_size_bytes", dm-bufio will react to this change
within 30 seconds and decrease memory consumption.

Depends-on: 1b0fb5a5 ("dm bufio: avoid a possible ABBA deadlock")
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 bbe86592
...@@ -1749,9 +1749,17 @@ static void __evict_old_buffers(struct dm_bufio_client *c, unsigned long age_hz) ...@@ -1749,9 +1749,17 @@ 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 retain_target = get_retain_buffers(c);
unsigned count; unsigned count;
LIST_HEAD(write_list);
dm_bufio_lock(c); dm_bufio_lock(c);
__check_watermark(c, &write_list);
if (unlikely(!list_empty(&write_list))) {
dm_bufio_unlock(c);
__flush_write_list(&write_list);
dm_bufio_lock(c);
}
count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY]; count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY];
list_for_each_entry_safe_reverse(b, tmp, &c->lru[LIST_CLEAN], lru_list) { list_for_each_entry_safe_reverse(b, tmp, &c->lru[LIST_CLEAN], lru_list) {
if (count <= retain_target) if (count <= retain_target)
...@@ -1776,6 +1784,8 @@ static void cleanup_old_buffers(void) ...@@ -1776,6 +1784,8 @@ static void cleanup_old_buffers(void)
mutex_lock(&dm_bufio_clients_lock); mutex_lock(&dm_bufio_clients_lock);
__cache_size_refresh();
list_for_each_entry(c, &dm_bufio_all_clients, client_list) list_for_each_entry(c, &dm_bufio_all_clients, client_list)
__evict_old_buffers(c, max_age_hz); __evict_old_buffers(c, max_age_hz);
......
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