diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2017-04-30 17:34:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-25 09:44:33 -0400 |
commit | e08047c90c8aa2c0bb2403c30b0692c7f147f200 (patch) | |
tree | 2d164a8af6a23b0d9345b76c47f1dc93e141e446 /drivers/md | |
parent | 98e7b9d45bf443b02a7b8aacb2e502042ea88441 (diff) |
dm bufio: check new buffer allocation watermark every 30 seconds
commit 390020ad2af9ca04844c4f3b1f299ad8746d84c8 upstream.
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: 1b0fb5a5b2 ("dm bufio: avoid a possible ABBA deadlock")
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-bufio.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index d0745965f8ec..c805fd9184bf 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
@@ -1782,9 +1782,17 @@ static void __evict_old_buffers(struct dm_bufio_client *c, unsigned long age_hz) | |||
1782 | struct dm_buffer *b, *tmp; | 1782 | struct dm_buffer *b, *tmp; |
1783 | unsigned retain_target = get_retain_buffers(c); | 1783 | unsigned retain_target = get_retain_buffers(c); |
1784 | unsigned count; | 1784 | unsigned count; |
1785 | LIST_HEAD(write_list); | ||
1785 | 1786 | ||
1786 | dm_bufio_lock(c); | 1787 | dm_bufio_lock(c); |
1787 | 1788 | ||
1789 | __check_watermark(c, &write_list); | ||
1790 | if (unlikely(!list_empty(&write_list))) { | ||
1791 | dm_bufio_unlock(c); | ||
1792 | __flush_write_list(&write_list); | ||
1793 | dm_bufio_lock(c); | ||
1794 | } | ||
1795 | |||
1788 | count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY]; | 1796 | count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY]; |
1789 | list_for_each_entry_safe_reverse(b, tmp, &c->lru[LIST_CLEAN], lru_list) { | 1797 | list_for_each_entry_safe_reverse(b, tmp, &c->lru[LIST_CLEAN], lru_list) { |
1790 | if (count <= retain_target) | 1798 | if (count <= retain_target) |
@@ -1809,6 +1817,8 @@ static void cleanup_old_buffers(void) | |||
1809 | 1817 | ||
1810 | mutex_lock(&dm_bufio_clients_lock); | 1818 | mutex_lock(&dm_bufio_clients_lock); |
1811 | 1819 | ||
1820 | __cache_size_refresh(); | ||
1821 | |||
1812 | list_for_each_entry(c, &dm_bufio_all_clients, client_list) | 1822 | list_for_each_entry(c, &dm_bufio_all_clients, client_list) |
1813 | __evict_old_buffers(c, max_age_hz); | 1823 | __evict_old_buffers(c, max_age_hz); |
1814 | 1824 | ||