linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Sergey Senozhatsky <senozhatsky@chromium.org>
To: Minchan Kim <minchan@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: Nitin Gupta <ngupta@vflare.org>,
	Suleiman Souhlal <suleiman@google.com>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	Sergey Senozhatsky <senozhatsky@chromium.org>
Subject: [PATCHv5 10/13] zram: Add algo parameter support to zram_recompress()
Date: Wed,  9 Nov 2022 20:50:44 +0900	[thread overview]
Message-ID: <20221109115047.2921851-11-senozhatsky@chromium.org> (raw)
In-Reply-To: <20221109115047.2921851-1-senozhatsky@chromium.org>

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

Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
 drivers/block/zram/zram_drv.c | 54 +++++++++++++++++++++++++++++------
 drivers/block/zram/zram_drv.h |  1 +
 2 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 67b58f2255db..89d25f60b33e 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1677,6 +1677,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;
 
@@ -1711,6 +1712,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);
@@ -1743,13 +1745,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;
 	}
 
@@ -1798,10 +1806,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;
@@ -1833,6 +1842,11 @@ static ssize_t recompress_store(struct device *dev,
 				return ret;
 			continue;
 		}
+
+		if (!strcmp(param, "algo")) {
+			algo = val;
+			continue;
+		}
 	}
 
 	if (threshold >= PAGE_SIZE)
@@ -1844,6 +1858,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;
@@ -1874,7 +1908,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) {
@@ -2110,6 +2144,7 @@ static void zram_destroy_comps(struct zram *zram)
 		if (!comp)
 			continue;
 		zcomp_destroy(comp);
+		zram->num_active_comps--;
 	}
 }
 
@@ -2177,6 +2212,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);
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index b80faae76835..473325415a74 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -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
 	 */
-- 
2.38.1.431.g37b22c650d-goog



  parent reply	other threads:[~2022-11-09 11:52 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-09 11:50 [PATCHv5 00/13] zram: Support multiple compression streams Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 01/13] zram: Preparation for multi-zcomp support Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 02/13] zram: Add recompression algorithm sysfs knob Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 03/13] zram: Factor out WB and non-WB zram read functions Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 04/13] zram: Introduce recompress sysfs knob Sergey Senozhatsky
2022-11-10 13:09   ` Nathan Chancellor
2022-11-10 14:31     ` Sergey Senozhatsky
2022-11-10 14:38       ` Sergey Senozhatsky
2022-11-10 15:18         ` Nathan Chancellor
2022-11-10 14:34   ` [PATCH] zram: we should always zero out err variable in recompress loop Sergey Senozhatsky
2022-11-14  2:14   ` [PATCH] zram: explicitly limit prio_max for static analyzers Sergey Senozhatsky
2022-11-15  0:41     ` Andrew Morton
2022-11-15  0:47       ` Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 05/13] zram: Add recompress flag to read_block_state() Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 06/13] zram: Clarify writeback_store() comment Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 07/13] zram: Use IS_ERR_VALUE() to check for zs_malloc() errors Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 08/13] zram: add size class equals check into recompression Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 09/13] zram: remove redundant checks from zram_recompress() Sergey Senozhatsky
2022-11-09 11:50 ` Sergey Senozhatsky [this message]
2022-11-09 11:50 ` [PATCHv5 11/13] documentation: Add zram recompression documentation Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 12/13] zram: add incompressible writeback Sergey Senozhatsky
2022-11-09 11:50 ` [PATCHv5 13/13] zram: Add incompressible flag to read_block_state() Sergey Senozhatsky
2022-11-09 21:46 ` [PATCHv5 00/13] zram: Support multiple compression streams Minchan Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221109115047.2921851-11-senozhatsky@chromium.org \
    --to=senozhatsky@chromium.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=minchan@kernel.org \
    --cc=ngupta@vflare.org \
    --cc=suleiman@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox