2023-04-18 06:48:28

by Alexey Romanov

[permalink] [raw]
Subject: [RFC PATCH v1 0/5] Introduce objects folding mechanism

Hello!

This RFC series adds feature which allows fold identical
zsmalloc objects into a single one.

Based on ZRAM version:
https://lore.kernel.org/lkml/Y3w8%2Fq%[email protected]/t/

Let's imagine that 3 objects with the same content got into zsmalloc:

+----------------+ +----------------+ +----------------+
| handle 1 | | handle 2 | | handle 3 |
+-------+--------+ +-------+--------+ +--------+-------+
| | |
| | |
+-------v--------+ +-------v---------+ +--------v-------+
|zsmalloc object| |zsmalloc object | |zsmalloc object|
++--------------++ +-+-------------+-+ ++--------------++
+--------------+ +-------------+ +--------------+
| buffer: "abc"| |buffer: "abc"| | buffer: "abc"|
+--------------+ +-------------+ +--------------+

As you can see, the data is duplicated. Fold mechanism saves
(after scanning objects) only one zsmalloc object. Here's
what happens after the scan and fold:

+----------------+ +----------------+ +----------------+
| handle 1 | | handle 2 | | handle 3 |
+-------+--------+ +-------+--------+ +--------+-------+
| | |
| | |
| +--------v---------+ |
+-----------> zsmalloc object <-----------+
+--+-------------+-+
+-------------+
|buffer: "abc"|
+-------------+

Thus, we reduced the amount of memory occupied by 3 times.

This mechanism doesn't affect the perf of the zsmalloc itself in
any way (maybe just a little bit on the zs_free() function).
In order to describe each such identical object, we (constantly)
need sizeof(fold_rbtree_node) bytes. Also, all struct size_class now
have new field struct rb_root fold_rbtree.

Testing on my system (8GB RAM + 1Gb ZRAM SWAP) showed that at high
loads, on average, when calling the fold mechanism, we can save
up to 15-20% of the memory usage.

This patch series adds a new sysfs node into ZRAM - trigger folding
and provides new field in mm_stat. This field shows how many pages
freed during folding:

$ cat /sys/block/zram0/mm_stat
431452160 332984392 339894272 0 339894272 282 0 51374 51374 0

$ echo 1 > /sys/block/zram0/fold

$ cat /sys/block/zram/mm_stat
431452160 270376848 287301504 0 339894272 282 0 51374 51374 6593

Alexey Romanov (5):
mm/zsmalloc: use ARRAY_SIZE in isolate_zspage()
mm/zsmalloc: get rid of PAGE_MASK
mm/zsmalloc: introduce objects folding mechanism
zram: add fold sysfs knob
zram: add pages_folded to stats

Documentation/admin-guide/blockdev/zram.rst | 2 +
drivers/block/zram/zram_drv.c | 30 +-
include/linux/zsmalloc.h | 4 +
mm/Kconfig | 9 +
mm/zsmalloc.c | 484 +++++++++++++++++++-
5 files changed, 513 insertions(+), 16 deletions(-)

--
2.38.1


2023-04-18 06:48:36

by Alexey Romanov

[permalink] [raw]
Subject: [RFC PATCH v1 5/5] zram: add pages_folded to stats

This counter show how many objects folded into single one
at the zsmalloc allocator level.

Signed-off-by: Alexey Romanov <[email protected]>
---
Documentation/admin-guide/blockdev/zram.rst | 2 ++
drivers/block/zram/zram_drv.c | 5 +++--
2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index e4551579cb12..349f13a2d310 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -209,6 +209,7 @@ compact WO trigger memory compaction
debug_stat RO this file is used for zram debugging purposes
backing_dev RW set up backend storage for zram to write out
idle WO mark allocated slot as idle
+fold WO trigger memory folding
====================== ====== ===============================================


@@ -267,6 +268,7 @@ line of text and contains the following stats separated by whitespace:
pages_compacted the number of pages freed during compaction
huge_pages the number of incompressible pages
huge_pages_since the number of incompressible pages since zram set up
+ pages_folded the number of pages freed during folding
================ =============================================================

File /sys/block/zram<id>/bd_stat
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 06a614d1643d..3012b297ade5 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1242,7 +1242,7 @@ static ssize_t mm_stat_show(struct device *dev,
max_used = atomic_long_read(&zram->stats.max_used_pages);

ret = scnprintf(buf, PAGE_SIZE,
- "%8llu %8llu %8llu %8lu %8ld %8llu %8lu %8llu %8llu\n",
+ "%8llu %8llu %8llu %8lu %8ld %8llu %8lu %8llu %8llu %8lu\n",
orig_size << PAGE_SHIFT,
(u64)atomic64_read(&zram->stats.compr_data_size),
mem_used << PAGE_SHIFT,
@@ -1251,7 +1251,8 @@ static ssize_t mm_stat_show(struct device *dev,
(u64)atomic64_read(&zram->stats.same_pages),
atomic_long_read(&pool_stats.pages_compacted),
(u64)atomic64_read(&zram->stats.huge_pages),
- (u64)atomic64_read(&zram->stats.huge_pages_since));
+ (u64)atomic64_read(&zram->stats.huge_pages_since),
+ atomic_long_read(&pool_stats.pages_folded));
up_read(&zram->init_lock);

return ret;
--
2.38.1

2023-05-02 10:42:34

by Alexey Romanov

[permalink] [raw]
Subject: Re: [RFC PATCH v1 0/5] Introduce objects folding mechanism

Hello!

On Tue, Apr 18, 2023 at 09:24:58AM +0300, Alexey Romanov wrote:
> Hello!
>
> This RFC series adds feature which allows fold identical
> zsmalloc objects into a single one.
>
> Based on ZRAM version:
> https://lore.kernel.org/lkml/Y3w8%2Fq%[email protected]/t/
>
> Let's imagine that 3 objects with the same content got into zsmalloc:
>
> +----------------+ +----------------+ +----------------+
> | handle 1 | | handle 2 | | handle 3 |
> +-------+--------+ +-------+--------+ +--------+-------+
> | | |
> | | |
> +-------v--------+ +-------v---------+ +--------v-------+
> |zsmalloc object| |zsmalloc object | |zsmalloc object|
> ++--------------++ +-+-------------+-+ ++--------------++
> +--------------+ +-------------+ +--------------+
> | buffer: "abc"| |buffer: "abc"| | buffer: "abc"|
> +--------------+ +-------------+ +--------------+
>
> As you can see, the data is duplicated. Fold mechanism saves
> (after scanning objects) only one zsmalloc object. Here's
> what happens after the scan and fold:
>
> +----------------+ +----------------+ +----------------+
> | handle 1 | | handle 2 | | handle 3 |
> +-------+--------+ +-------+--------+ +--------+-------+
> | | |
> | | |
> | +--------v---------+ |
> +-----------> zsmalloc object <-----------+
> +--+-------------+-+
> +-------------+
> |buffer: "abc"|
> +-------------+
>
> Thus, we reduced the amount of memory occupied by 3 times.
>
> This mechanism doesn't affect the perf of the zsmalloc itself in
> any way (maybe just a little bit on the zs_free() function).
> In order to describe each such identical object, we (constantly)
> need sizeof(fold_rbtree_node) bytes. Also, all struct size_class now
> have new field struct rb_root fold_rbtree.
>
> Testing on my system (8GB RAM + 1Gb ZRAM SWAP) showed that at high
> loads, on average, when calling the fold mechanism, we can save
> up to 15-20% of the memory usage.
>
> This patch series adds a new sysfs node into ZRAM - trigger folding
> and provides new field in mm_stat. This field shows how many pages
> freed during folding:
>
> $ cat /sys/block/zram0/mm_stat
> 431452160 332984392 339894272 0 339894272 282 0 51374 51374 0
>
> $ echo 1 > /sys/block/zram0/fold
>
> $ cat /sys/block/zram/mm_stat
> 431452160 270376848 287301504 0 339894272 282 0 51374 51374 6593
>
> Alexey Romanov (5):
> mm/zsmalloc: use ARRAY_SIZE in isolate_zspage()
> mm/zsmalloc: get rid of PAGE_MASK
> mm/zsmalloc: introduce objects folding mechanism
> zram: add fold sysfs knob
> zram: add pages_folded to stats
>
> Documentation/admin-guide/blockdev/zram.rst | 2 +
> drivers/block/zram/zram_drv.c | 30 +-
> include/linux/zsmalloc.h | 4 +
> mm/Kconfig | 9 +
> mm/zsmalloc.c | 484 +++++++++++++++++++-
> 5 files changed, 513 insertions(+), 16 deletions(-)
>
> --
> 2.38.1
>

Really sorry for the noise, but could you comment on my patchset and
results? We have moved away from the terms and concepts used in the
patent we discussed in the ZRAM version, and I believe we can safely use
these changes in zsmalloc.

--
Thank you,
Alexey