mirror of
https://github.com/torvalds/linux
synced 2024-10-06 19:34:19 +00:00
zram: add max_pages param to recompression
Introduce "max_pages" param to recompress device attribute which sets an upper limit on the number of entries (pages) zram attempts to recompress (in this particular recompression call). S/W recompression can be quite expensive so limiting the number of pages recompress touches can be quite helpful. Link: https://lkml.kernel.org/r/20240329094050.2815699-1-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org> Acked-by: Brian Geffon <bgeffon@google.com> Cc: Minchan Kim <minchan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
ba42b524a0
commit
34efe1c3b6
|
@ -466,6 +466,11 @@ of equal or greater size:::
|
||||||
#recompress idle pages larger than 2000 bytes
|
#recompress idle pages larger than 2000 bytes
|
||||||
echo "type=idle threshold=2000" > /sys/block/zramX/recompress
|
echo "type=idle threshold=2000" > /sys/block/zramX/recompress
|
||||||
|
|
||||||
|
It is also possible to limit the number of pages zram re-compression will
|
||||||
|
attempt to recompress:::
|
||||||
|
|
||||||
|
echo "type=huge_idle max_pages=42" > /sys/block/zramX/recompress
|
||||||
|
|
||||||
Recompression of idle pages requires memory tracking.
|
Recompression of idle pages requires memory tracking.
|
||||||
|
|
||||||
During re-compression for every page, that matches re-compression criteria,
|
During re-compression for every page, that matches re-compression criteria,
|
||||||
|
|
|
@ -1568,7 +1568,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec,
|
||||||
* Corresponding ZRAM slot should be locked.
|
* Corresponding ZRAM slot should be locked.
|
||||||
*/
|
*/
|
||||||
static int zram_recompress(struct zram *zram, u32 index, struct page *page,
|
static int zram_recompress(struct zram *zram, u32 index, struct page *page,
|
||||||
u32 threshold, u32 prio, u32 prio_max)
|
u64 *num_recomp_pages, u32 threshold, u32 prio,
|
||||||
|
u32 prio_max)
|
||||||
{
|
{
|
||||||
struct zcomp_strm *zstrm = NULL;
|
struct zcomp_strm *zstrm = NULL;
|
||||||
unsigned long handle_old;
|
unsigned long handle_old;
|
||||||
|
@ -1645,6 +1646,15 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page,
|
||||||
if (!zstrm)
|
if (!zstrm)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement the limit (if set) on pages we can recompress, even
|
||||||
|
* when current recompression was unsuccessful or did not compress
|
||||||
|
* the page below the threshold, because we still spent resources
|
||||||
|
* on it.
|
||||||
|
*/
|
||||||
|
if (*num_recomp_pages)
|
||||||
|
*num_recomp_pages -= 1;
|
||||||
|
|
||||||
if (class_index_new >= class_index_old) {
|
if (class_index_new >= class_index_old) {
|
||||||
/*
|
/*
|
||||||
* Secondary algorithms failed to re-compress the page
|
* Secondary algorithms failed to re-compress the page
|
||||||
|
@ -1710,6 +1720,7 @@ static ssize_t recompress_store(struct device *dev,
|
||||||
struct zram *zram = dev_to_zram(dev);
|
struct zram *zram = dev_to_zram(dev);
|
||||||
unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
|
unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
|
||||||
char *args, *param, *val, *algo = NULL;
|
char *args, *param, *val, *algo = NULL;
|
||||||
|
u64 num_recomp_pages = ULLONG_MAX;
|
||||||
u32 mode = 0, threshold = 0;
|
u32 mode = 0, threshold = 0;
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
@ -1732,6 +1743,17 @@ static ssize_t recompress_store(struct device *dev,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(param, "max_pages")) {
|
||||||
|
/*
|
||||||
|
* Limit the number of entries (pages) we attempt to
|
||||||
|
* recompress.
|
||||||
|
*/
|
||||||
|
ret = kstrtoull(val, 10, &num_recomp_pages);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(param, "threshold")) {
|
if (!strcmp(param, "threshold")) {
|
||||||
/*
|
/*
|
||||||
* We will re-compress only idle objects equal or
|
* We will re-compress only idle objects equal or
|
||||||
|
@ -1788,6 +1810,9 @@ static ssize_t recompress_store(struct device *dev,
|
||||||
for (index = 0; index < nr_pages; index++) {
|
for (index = 0; index < nr_pages; index++) {
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
if (!num_recomp_pages)
|
||||||
|
break;
|
||||||
|
|
||||||
zram_slot_lock(zram, index);
|
zram_slot_lock(zram, index);
|
||||||
|
|
||||||
if (!zram_allocated(zram, index))
|
if (!zram_allocated(zram, index))
|
||||||
|
@ -1807,8 +1832,8 @@ static ssize_t recompress_store(struct device *dev,
|
||||||
zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE))
|
zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE))
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
err = zram_recompress(zram, index, page, threshold,
|
err = zram_recompress(zram, index, page, &num_recomp_pages,
|
||||||
prio, prio_max);
|
threshold, prio, prio_max);
|
||||||
next:
|
next:
|
||||||
zram_slot_unlock(zram, index);
|
zram_slot_unlock(zram, index);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
Loading…
Reference in a new issue