From: Minchan Kim <minchan@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-mm <linux-mm@kvack.org>, Jens Axboe <axboe@kernel.dk>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
Seth Jennings <sjenning@redhat.com>,
Sergey Senozhatsky <senozhatsky@chromium.org>,
Minchan Kim <minchan@kernel.org>
Subject: [PATCH 2/3] zram: support frontswap
Date: Mon, 10 Jul 2023 15:16:58 -0700 [thread overview]
Message-ID: <20230710221659.2473460-3-minchan@kernel.org> (raw)
In-Reply-To: <20230710221659.2473460-1-minchan@kernel.org>
With frontswap, zram can perform swapout 13% faster, which restores
its original performance with rw_page.
200M swapout using MADV_PAGEOUT:
Before: 4355ms After: 3786ms
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
drivers/block/zram/Kconfig | 1 +
drivers/block/zram/zram_drv.c | 98 +++++++++++++++++++++++++++++++++++
drivers/block/zram/zram_drv.h | 1 +
3 files changed, 100 insertions(+)
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 0386b7da02aa..a841d6d14c74 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -4,6 +4,7 @@ config ZRAM
depends on BLOCK && SYSFS && MMU
depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842
select ZSMALLOC
+ select FRONTSWAP
help
Creates virtual block devices called /dev/zramX (X = 0, 1, ...).
Pages written to these disks are compressed and stored in memory
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 5d258a28ec43..5e973c982235 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -33,6 +33,8 @@
#include <linux/debugfs.h>
#include <linux/cpuhotplug.h>
#include <linux/part_stat.h>
+#include <linux/swap.h>
+#include <linux/frontswap.h>
#include "zram_drv.h"
@@ -2170,6 +2172,90 @@ static struct attribute *zram_disk_attrs[] = {
ATTRIBUTE_GROUPS(zram_disk);
+static struct zram *zram_swaps[MAX_SWAPFILES];
+static LIST_HEAD(zram_list);
+static DEFINE_SPINLOCK(zram_list_lock);
+
+static int zram_frontswap_store(unsigned int type, pgoff_t index,
+ struct page *page)
+{
+ int err;
+ struct zram *zram = zram_swaps[type];
+
+ err = zram_write_page(zram, page, index);
+ if (!err) {
+ zram_slot_lock(zram, index);
+ zram_accessed(zram, index);
+ zram_slot_unlock(zram, index);
+ }
+
+ return err;
+}
+
+static int zram_frontswap_load(unsigned int type, pgoff_t index,
+ struct page *page, bool *exclusive)
+{
+ int err;
+ struct zram *zram = zram_swaps[type];
+
+ zram_slot_lock(zram, index);
+ if (zram_test_flag(zram, index, ZRAM_WB)) {
+ zram_slot_lock(zram, index);
+ return -1;
+ }
+
+ err = zram_read_from_zspool(zram, page, index);
+ if (!err)
+ zram_accessed(zram, index);
+ zram_slot_unlock(zram, index);
+
+ return err;
+}
+
+static void zram_frontswap_invalidate_area(unsigned int type)
+{
+ struct zram *zram = zram_swaps[type];
+
+ if (!zram)
+ return;
+}
+
+static void zram_frontswap_init(unsigned int type, struct block_device *bdev)
+{
+ struct zram *zram;
+
+ spin_lock(&zram_list_lock);
+ list_for_each_entry(zram, &zram_list, list) {
+ if (&zram_devops == bdev->bd_disk->fops) {
+ zram_swaps[type] = zram;
+ break;
+ }
+ }
+ spin_unlock(&zram_list_lock);
+}
+
+static void zram_frontswap_invalidate_page(unsigned int type, pgoff_t offset)
+{
+ struct zram *zram = zram_swaps[type];
+
+ if (!zram_slot_trylock(zram, offset)) {
+ atomic64_inc(&zram->stats.miss_free);
+ return;
+ }
+
+ zram_free_page(zram, offset);
+ zram_slot_unlock(zram, offset);
+}
+
+static const struct frontswap_ops zram_frontswap_ops = {
+ .store = zram_frontswap_store,
+ .load = zram_frontswap_load,
+ .init = zram_frontswap_init,
+ .invalidate_area = zram_frontswap_invalidate_area,
+ .invalidate_page = zram_frontswap_invalidate_page,
+ .init = zram_frontswap_init
+};
+
/*
* Allocate and initialize new zram device. the function returns
* '>= 0' device_id upon success, and negative value otherwise.
@@ -2246,6 +2332,10 @@ static int zram_add(void)
comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
+ spin_lock(&zram_list_lock);
+ list_add(&zram->list, &zram_list);
+ spin_unlock(&zram_list_lock);
+
zram_debugfs_register(zram);
pr_info("Added device: %s\n", zram->disk->disk_name);
return device_id;
@@ -2303,6 +2393,11 @@ static int zram_remove(struct zram *zram)
zram_reset_device(zram);
put_disk(zram->disk);
+
+ spin_lock(&zram_list_lock);
+ list_del(&zram->list);
+ spin_unlock(&zram_list_lock);
+
kfree(zram);
return 0;
}
@@ -2428,6 +2523,9 @@ static int __init zram_init(void)
num_devices--;
}
+ if (frontswap_register_ops(&zram_frontswap_ops))
+ pr_info("Frontswap is not used, which is suboptimal for zram swap.\n");
+
return 0;
out_error:
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index ca7a15bd4845..0f52d2da8512 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -139,5 +139,6 @@ struct zram {
#ifdef CONFIG_ZRAM_MEMORY_TRACKING
struct dentry *debugfs_dir;
#endif
+ struct list_head list;
};
#endif
--
2.41.0.255.g8b1d071c50-goog
next prev parent reply other threads:[~2023-07-10 22:17 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-10 22:16 [PATCH 0/3] zram: use frontswap for zram swap usecase Minchan Kim
2023-07-10 22:16 ` [PATCH 1/3] frontswap: support backing_dev Minchan Kim
2023-07-10 22:16 ` Minchan Kim [this message]
2023-07-11 10:08 ` [PATCH 2/3] zram: support frontswap Alexey Romanov
2023-07-11 23:58 ` Minchan Kim
2023-07-10 22:16 ` [PATCH 3/3] zram: remove swap_slot_free_notify Minchan Kim
2023-07-11 10:09 ` Alexey Romanov
2023-07-11 5:17 ` [PATCH 0/3] zram: use frontswap for zram swap usecase Christoph Hellwig
2023-07-11 17:52 ` Nhat Pham
2023-07-11 23:56 ` 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=20230710221659.2473460-3-minchan@kernel.org \
--to=minchan@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=konrad.wilk@oracle.com \
--cc=linux-mm@kvack.org \
--cc=senozhatsky@chromium.org \
--cc=sjenning@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.