linux-stable/drivers/block
Sergey Senozhatsky 3f909a60ce zram: rework recompress target selection strategy
Target slot selection for recompression is just a simple iteration over
zram->table entries (stored pages) from slot 0 to max slot.  Given that
zram->table slots are written in random order and are not sorted by size,
a simple iteration over slots selects suboptimal targets for
recompression.  This is not a problem if we recompress every single
zram->table slot, but we never do that in reality.  In reality we limit
the number of slots we can recompress (via max_pages parameter) and hence
proper slot selection becomes very important.  The strategy is quite
simple, suppose we have two candidate slots for recompression, one of size
48 bytes and one of size 2800 bytes, and we can recompress only one, then
it certainly makes more sense to pick 2800 entry for recompression. 
Because even if we manage to compress 48 bytes objects even further the
savings are going to be very small.  Potential savings after good
re-compression of 2800 bytes objects are much higher.

This patch reworks slot selection and introduces the strategy described
above: among candidate slots always select the biggest ones first.

For that the patch introduces zram_pp_ctl (post-processing) structure
which holds NUM_PP_BUCKETS pp buckets of slots.  Slots are assigned to a
particular group based on their sizes - the larger the size of the slot
the higher the group index.  This, basically, sorts slots by size in liner
time (we still perform just one iteration over zram->table slots).  When
we select slot for recompression we always first lookup in higher pp
buckets (those that hold the largest slots).  Which achieves the desired
behavior.

TEST
====

A very simple demonstration: zram is configured with zstd, and zstd with
dict as a recompression stream.  A limited (max 4096 pages) recompression
is performed then, with a log of sizes of slots that were recompressed. 
You can see that patched zram selects slots for recompression in
significantly different manner, which leads to higher memory savings (see
column #2 of mm_stat output).

BASE
----

*** initial state of zram device
/sys/block/zram0/mm_stat
1750994944 504491413 514203648        0 514203648        1        0    34204    34204

*** recompress idle max_pages=4096
/sys/block/zram0/mm_stat
1750994944 504262229 514953216        0 514203648        1        0    34204    34204

Sizes of selected objects for recompression:
... 45 58 24 226 91 40 24 24 24 424 2104 93 2078 2078 2078 959 154 ...

PATCHED
-------

*** initial state of zram device
/sys/block/zram0/mm_stat
1750982656 504492801 514170880        0 514170880        1        0    34204    34204

*** recompress idle max_pages=4096
/sys/block/zram0/mm_stat
1750982656 503716710 517586944        0 514170880        1        0    34204    34204

Sizes of selected objects for recompression:
... 3680 3694 3667 3590 3614 3553 3537 3548 3550 3542 3543 3537 ...

Note, pp-slots are not strictly sorted, there is a PP_BUCKET_SIZE_RANGE
variation of sizes within particular bucket.

[senozhatsky@chromium.org: do not skip the first bucket]
  Link: https://lkml.kernel.org/r/20241001085634.1948384-1-senozhatsky@chromium.org
Link: https://lkml.kernel.org/r/20240917021020.883356-4-senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2024-11-05 16:56:22 -08:00
..
aoe block-6.12-20241004 2024-10-04 10:43:44 -07:00
drbd block-6.12-20241018 2024-10-18 15:53:00 -07:00
mtip32xx [tree-wide] finally take no_llseek out 2024-09-27 08:18:43 -07:00
null_blk null_blk: Don't bother validating blocksize 2024-07-09 00:00:17 -06:00
rnbd block/rnbd-srv: Add sanity check and remove redundant assignment 2024-08-28 08:50:35 -06:00
xen-blkback xen/blkback: add missing MODULE_DESCRIPTION() macro 2024-07-10 00:21:18 -06:00
zram zram: rework recompress target selection strategy 2024-11-05 16:56:22 -08:00
amiflop.c Merge branch 'for-6.11/block-limits' into for-6.11/block 2024-06-19 08:14:49 -06:00
ataflop.c Merge branch 'for-6.11/block-limits' into for-6.11/block 2024-06-19 08:14:49 -06:00
brd.c brd: add missing MODULE_DESCRIPTION() macro 2024-06-24 08:38:52 -06:00
floppy.c floppy: add missing MODULE_DESCRIPTION() macro 2024-07-10 00:22:03 -06:00
Kconfig rust: block: add rnull, Rust null_blk implementation 2024-06-14 07:45:04 -06:00
loop.c for-6.11/block-20240710 2024-07-15 14:20:22 -07:00
Makefile rust: block: add rnull, Rust null_blk implementation 2024-06-14 07:45:04 -06:00
n64cart.c block: move the nonrot flag to queue_limits 2024-06-19 07:58:28 -06:00
nbd.c nbd: correct the maximum value for discard sectors 2024-09-06 08:31:40 -06:00
pktcdvd.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
ps3disk.c block: move the nonrot flag to queue_limits 2024-06-19 07:58:28 -06:00
ps3vram.c block: pass a queue_limits argument to blk_alloc_disk 2024-02-19 16:58:23 -07:00
rbd_types.h libceph, rbd: replace zero-length array with flexible-array 2020-06-01 13:22:53 +02:00
rbd.c A small patchset to address bogus I/O errors and ultimately an 2024-07-26 10:34:42 -07:00
rnull.rs rust: block: add rnull, Rust null_blk implementation 2024-06-14 07:45:04 -06:00
sunvdc.c block: move the nonrot flag to queue_limits 2024-06-19 07:58:28 -06:00
swim3.c block: move the nonrot flag to queue_limits 2024-06-19 07:58:28 -06:00
swim_asm.S treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
swim.c block: move the nonrot flag to queue_limits 2024-06-19 07:58:28 -06:00
ublk_drv.c ublk: don't allow user copy for unprivileged device 2024-10-16 08:08:18 -06:00
virtio_blk.c virtio: features, fixes, cleanups 2024-07-19 11:57:55 -07:00
xen-blkfront.c xen-blkfront: fix sector_size propagation to the block layer 2024-07-02 08:58:12 -06:00
z2ram.c z2ram: add missing MODULE_DESCRIPTION() macro 2024-06-19 07:54:00 -06:00