In the current implementation entry's previously allocated
memory is released in the very last moment, when we already
have allocated a new memory for new data. This, basically,
temporarily increases memory usage for no good reason. For
example, consider the case when both old (stale) and new
entry data are incompressible so such entry will temporarily
use two physical pages - one for stale (old) data and one
for new data. We can release old memory as soon as we get
a write request for entry.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/zram_drv.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 882a32d46a75..987d72f2249c 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1640,6 +1640,11 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index)
unsigned long element = 0;
enum zram_pageflags flags = 0;
+ /* First, free memory allocated to this slot (if any) */
+ zram_slot_lock(zram, index);
+ zram_free_page(zram, index);
+ zram_slot_unlock(zram, index);
+
mem = kmap_local_page(page);
if (page_same_filled(mem, &element)) {
kunmap_local(mem);
@@ -1728,13 +1733,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index)
zs_unmap_object(zram->mem_pool, handle);
atomic64_add(comp_len, &zram->stats.compr_data_size);
out:
- /*
- * Free memory associated with this sector
- * before overwriting unused sectors.
- */
zram_slot_lock(zram, index);
- zram_free_page(zram, index);
-
if (comp_len == PAGE_SIZE) {
zram_set_flag(zram, index, ZRAM_HUGE);
atomic64_inc(&zram->stats.huge_pages);
--
2.47.0.371.ga323438b13-goog