Skip to content

Commit

Permalink
zram: add algo parameter support to zram_recompress()
Browse files Browse the repository at this point in the history
Recompression iterates through all the registered secondary compression
algorithms in order of their priorities so that we have higher chances of
finding the algorithm that compresses a particular page.  This, however,
may not always be best approach and sometimes we may want to limit
recompression to only one particular algorithm.  For instance, when a
higher priority algorithm uses too much power and device has a relatively
low battery level we may want to limit recompression to use only a lower
priority algorithm, which uses less power.

Introduce algo= parameter support to recompression sysfs knob so that
user-sapce can request recompression with particular algorithm only:

  echo "type=idle algo=zstd" > /sys/block/zramX/recompress

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Sergey Senozhatsky <[email protected]>
Acked-by: Minchan Kim <[email protected]>
Cc: Alexey Romanov <[email protected]>
Cc: Nhat Pham <[email protected]>
Cc: Nitin Gupta <[email protected]>
Cc: Suleiman Souhlal <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
sergey-senozhatsky authored and akpm00 committed Nov 30, 2022
1 parent 4942cf6 commit a55cf96
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
54 changes: 45 additions & 9 deletions drivers/block/zram/zram_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1674,6 +1674,7 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page,
unsigned int comp_len_new;
unsigned int class_index_old;
unsigned int class_index_new;
u32 num_recomps = 0;
void *src, *dst;
int ret;

Expand Down Expand Up @@ -1708,6 +1709,7 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page,
if (prio <= zram_get_priority(zram, index))
continue;

num_recomps++;
zstrm = zcomp_stream_get(zram->comps[prio]);
src = kmap_atomic(page);
ret = zcomp_compress(zstrm, src, &comp_len_new);
Expand Down Expand Up @@ -1740,13 +1742,19 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page,
if (!zstrm)
return 0;

/*
* All secondary algorithms failed to re-compress the page in a way
* that would save memory, mark the object as incompressible so that
* we will not try to compress it again.
*/
if (class_index_new >= class_index_old) {
zram_set_flag(zram, index, ZRAM_INCOMPRESSIBLE);
/*
* Secondary algorithms failed to re-compress the page
* in a way that would save memory, mark the object as
* incompressible so that we will not try to compress
* it again.
*
* We need to make sure that all secondary algorithms have
* failed, so we test if the number of recompressions matches
* the number of active secondary algorithms.
*/
if (num_recomps == zram->num_active_comps - 1)
zram_set_flag(zram, index, ZRAM_INCOMPRESSIBLE);
return 0;
}

Expand Down Expand Up @@ -1795,10 +1803,11 @@ static ssize_t recompress_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
u32 prio = ZRAM_SECONDARY_COMP, prio_max = ZRAM_MAX_COMPS;
struct zram *zram = dev_to_zram(dev);
u32 mode = 0, threshold = 0, prio = ZRAM_SECONDARY_COMP;
unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
char *args, *param, *val;
char *args, *param, *val, *algo = NULL;
u32 mode = 0, threshold = 0;
unsigned long index;
struct page *page;
ssize_t ret;
Expand Down Expand Up @@ -1830,6 +1839,11 @@ static ssize_t recompress_store(struct device *dev,
return ret;
continue;
}

if (!strcmp(param, "algo")) {
algo = val;
continue;
}
}

if (threshold >= PAGE_SIZE)
Expand All @@ -1841,6 +1855,26 @@ static ssize_t recompress_store(struct device *dev,
goto release_init_lock;
}

if (algo) {
bool found = false;

for (; prio < ZRAM_MAX_COMPS; prio++) {
if (!zram->comp_algs[prio])
continue;

if (!strcmp(zram->comp_algs[prio], algo)) {
prio_max = min(prio + 1, ZRAM_MAX_COMPS);
found = true;
break;
}
}

if (!found) {
ret = -EINVAL;
goto release_init_lock;
}
}

page = alloc_page(GFP_KERNEL);
if (!page) {
ret = -ENOMEM;
Expand Down Expand Up @@ -1871,7 +1905,7 @@ static ssize_t recompress_store(struct device *dev,
goto next;

err = zram_recompress(zram, index, page, threshold,
prio, ZRAM_MAX_COMPS);
prio, prio_max);
next:
zram_slot_unlock(zram, index);
if (err) {
Expand Down Expand Up @@ -2107,6 +2141,7 @@ static void zram_destroy_comps(struct zram *zram)
if (!comp)
continue;
zcomp_destroy(comp);
zram->num_active_comps--;
}
}

Expand Down Expand Up @@ -2174,6 +2209,7 @@ static ssize_t disksize_store(struct device *dev,
}

zram->comps[prio] = comp;
zram->num_active_comps++;
}
zram->disksize = disksize;
set_capacity_and_notify(zram->disk, zram->disksize >> SECTOR_SHIFT);
Expand Down
1 change: 1 addition & 0 deletions drivers/block/zram/zram_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ struct zram {
*/
u64 disksize; /* bytes */
const char *comp_algs[ZRAM_MAX_COMPS];
s8 num_active_comps;
/*
* zram is claimed so open request will be failed
*/
Expand Down

0 comments on commit a55cf96

Please sign in to comment.