zram: add algo parameter support to zram_recompress()
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/20221109115047.2921851-11-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org> Acked-by: Minchan Kim <minchan@kernel.org> Cc: Alexey Romanov <avromanov@sberdevices.ru> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Nitin Gupta <ngupta@vflare.org> Cc: Suleiman Souhlal <suleiman@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Родитель
4942cf6ad0
Коммит
a55cf9648d
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -2107,6 +2141,7 @@ static void zram_destroy_comps(struct zram *zram)
|
|||
if (!comp)
|
||||
continue;
|
||||
zcomp_destroy(comp);
|
||||
zram->num_active_comps--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче