aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2017-04-30 17:34:53 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-25 09:44:33 -0400
commite08047c90c8aa2c0bb2403c30b0692c7f147f200 (patch)
tree2d164a8af6a23b0d9345b76c47f1dc93e141e446 /drivers/md
parent98e7b9d45bf443b02a7b8aacb2e502042ea88441 (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.c10
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