summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/blockdev/zram.rst9
-rw-r--r--drivers/block/zram/zram_drv.c84
2 files changed, 24 insertions, 69 deletions
diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index 967b58c3aad2..60b07a7e30cd 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -533,15 +533,6 @@ unexpected results when the same algorithm is configured with different
priorities (e.g. different parameters). `priority` is the only way to
guarantee that the expected algorithm will be used.
-During re-compression for every page, that matches re-compression criteria,
-ZRAM iterates the list of registered alternative compression algorithms in
-order of their priorities. ZRAM stops either when re-compression was
-successful (re-compressed object is smaller in size than the original one)
-and matches re-compression criteria (e.g. size threshold) or when there are
-no secondary algorithms left to try. If none of the secondary algorithms can
-successfully re-compressed the page such a page is marked as incompressible,
-so ZRAM will not attempt to re-compress it in the future.
-
memory tracking
===============
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 74c522c14c78..48fb6e52de42 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -2336,7 +2336,7 @@ static bool highest_priority_algorithm(struct zram *zram, u32 prio)
return true;
}
-static int scan_slots_for_recompress(struct zram *zram, u32 mode, u32 prio_max,
+static int scan_slots_for_recompress(struct zram *zram, u32 mode, u32 prio,
struct zram_pp_ctl *ctl)
{
unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
@@ -2362,8 +2362,8 @@ static int scan_slots_for_recompress(struct zram *zram, u32 mode, u32 prio_max,
test_slot_flag(zram, index, ZRAM_INCOMPRESSIBLE))
goto next;
- /* Already compressed with same of higher priority */
- if (get_slot_comp_priority(zram, index) + 1 >= prio_max)
+ /* Already compressed with same or higher priority */
+ if (get_slot_comp_priority(zram, index) >= prio)
goto next;
ok = place_pp_slot(zram, ctl, index);
@@ -2384,8 +2384,7 @@ next:
* Corresponding ZRAM slot should be locked.
*/
static int recompress_slot(struct zram *zram, u32 index, struct page *page,
- u64 *num_recomp_pages, u32 threshold, u32 prio,
- u32 prio_max)
+ u64 *num_recomp_pages, u32 threshold, u32 prio)
{
struct zcomp_strm *zstrm = NULL;
unsigned long handle_old;
@@ -2397,6 +2396,9 @@ static int recompress_slot(struct zram *zram, u32 index, struct page *page,
void *src;
int ret = 0;
+ if (!zram->comps[prio])
+ return -EINVAL;
+
handle_old = get_slot_handle(zram, index);
if (!handle_old)
return -EINVAL;
@@ -2419,51 +2421,10 @@ static int recompress_slot(struct zram *zram, u32 index, struct page *page,
*/
clear_slot_flag(zram, index, ZRAM_IDLE);
- class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old);
-
- prio = max(prio, get_slot_comp_priority(zram, index) + 1);
- /*
- * Recompression slots scan should not select slots that are
- * already compressed with a higher priority algorithm, but
- * just in case
- */
- if (prio >= prio_max)
- return 0;
-
- /*
- * Iterate the secondary comp algorithms list (in order of priority)
- * and try to recompress the page.
- */
- for (; prio < prio_max; prio++) {
- if (!zram->comps[prio])
- continue;
-
- zstrm = zcomp_stream_get(zram->comps[prio]);
- src = kmap_local_page(page);
- ret = zcomp_compress(zram->comps[prio], zstrm,
- src, &comp_len_new);
- kunmap_local(src);
-
- if (ret) {
- zcomp_stream_put(zstrm);
- zstrm = NULL;
- break;
- }
-
- class_index_new = zs_lookup_class_index(zram->mem_pool,
- comp_len_new);
-
- /* Continue until we make progress */
- if (class_index_new >= class_index_old ||
- (threshold && comp_len_new >= threshold)) {
- zcomp_stream_put(zstrm);
- zstrm = NULL;
- continue;
- }
-
- /* Recompression was successful so break out */
- break;
- }
+ zstrm = zcomp_stream_get(zram->comps[prio]);
+ src = kmap_local_page(page);
+ ret = zcomp_compress(zram->comps[prio], zstrm, src, &comp_len_new);
+ kunmap_local(src);
/*
* Decrement the limit (if set) on pages we can recompress, even
@@ -2474,11 +2435,18 @@ static int recompress_slot(struct zram *zram, u32 index, struct page *page,
if (*num_recomp_pages)
*num_recomp_pages -= 1;
- /* Compression error */
- if (ret)
+ if (ret) {
+ zcomp_stream_put(zstrm);
return ret;
+ }
+
+ class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old);
+ class_index_new = zs_lookup_class_index(zram->mem_pool, comp_len_new);
+
+ if (class_index_new >= class_index_old ||
+ (threshold && comp_len_new >= threshold)) {
+ zcomp_stream_put(zstrm);
- if (!zstrm) {
/*
* Secondary algorithms failed to re-compress the page
* in a way that would save memory.
@@ -2528,11 +2496,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);
char *args, *param, *val, *algo = NULL;
u64 num_recomp_pages = ULLONG_MAX;
struct zram_pp_ctl *ctl = NULL;
+ u32 prio = ZRAM_SECONDARY_COMP;
struct zram_pp_slot *pps;
u32 mode = 0, threshold = 0;
struct page *page = NULL;
@@ -2586,8 +2554,6 @@ static ssize_t recompress_store(struct device *dev,
ret = kstrtouint(val, 10, &prio);
if (ret)
return ret;
-
- prio_max = min(prio + 1, ZRAM_MAX_COMPS);
continue;
}
}
@@ -2607,7 +2573,6 @@ static ssize_t recompress_store(struct device *dev,
continue;
if (!strcmp(zram->comp_algs[prio], algo)) {
- prio_max = min(prio + 1, ZRAM_MAX_COMPS);
found = true;
break;
}
@@ -2636,7 +2601,7 @@ static ssize_t recompress_store(struct device *dev,
goto out;
}
- scan_slots_for_recompress(zram, mode, prio_max, ctl);
+ scan_slots_for_recompress(zram, mode, prio, ctl);
ret = len;
while ((pps = select_pp_slot(ctl))) {
@@ -2650,8 +2615,7 @@ static ssize_t recompress_store(struct device *dev,
goto next;
err = recompress_slot(zram, pps->index, page,
- &num_recomp_pages, threshold,
- prio, prio_max);
+ &num_recomp_pages, threshold, prio);
next:
slot_unlock(zram, pps->index);
release_pp_slot(zram, pps);