All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] zram: use frontswap for zram swap usecase
@ 2023-07-10 22:16 Minchan Kim
  2023-07-10 22:16 ` [PATCH 1/3] frontswap: support backing_dev Minchan Kim
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Minchan Kim @ 2023-07-10 22:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-mm, Jens Axboe, Konrad Rzeszutek Wilk, Seth Jennings,
	Sergey Senozhatsky, Minchan Kim

This patchset uses frontswap for zram swap usecase and remove
swap_slot_free_notify swap specific operation in block device.
It shows 13% swapout improvement for MADV_PAGEOUT.

Minchan Kim (3):
  frontswap: support backing_dev
  zram: support frontswap
  zram: remove swap_slot_free_notify

 Documentation/filesystems/locking.rst |   5 --
 drivers/block/zram/Kconfig            |   1 +
 drivers/block/zram/zram_drv.c         | 116 ++++++++++++++++++++++----
 drivers/block/zram/zram_drv.h         |   1 +
 include/linux/blkdev.h                |   2 -
 include/linux/frontswap.h             |   7 +-
 mm/frontswap.c                        |   4 +-
 mm/swapfile.c                         |  11 +--
 mm/zswap.c                            |   2 +-
 9 files changed, 110 insertions(+), 39 deletions(-)

-- 
2.41.0.255.g8b1d071c50-goog



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/3] frontswap: support backing_dev
  2023-07-10 22:16 [PATCH 0/3] zram: use frontswap for zram swap usecase Minchan Kim
@ 2023-07-10 22:16 ` Minchan Kim
  2023-07-10 22:16 ` [PATCH 2/3] zram: support frontswap Minchan Kim
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Minchan Kim @ 2023-07-10 22:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-mm, Jens Axboe, Konrad Rzeszutek Wilk, Seth Jennings,
	Sergey Senozhatsky, Minchan Kim

Modify frontswap to be used as a block device driver for swap
partitions.

Signed-off-by: Minchan Kim <minchan@kernel.org>
---
 include/linux/frontswap.h | 7 +++++--
 mm/frontswap.c            | 4 ++--
 mm/swapfile.c             | 3 ++-
 mm/zswap.c                | 2 +-
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h
index eaa0ac5f9003..466d617dc3c7 100644
--- a/include/linux/frontswap.h
+++ b/include/linux/frontswap.h
@@ -7,8 +7,10 @@
 #include <linux/bitops.h>
 #include <linux/jump_label.h>
 
+struct block_device;
+
 struct frontswap_ops {
-	void (*init)(unsigned); /* this swap type was just swapon'ed */
+	void (*init)(unsigned, struct block_device *); /* this swap type was just swapon'ed */
 	int (*store)(unsigned, pgoff_t, struct page *); /* store a page */
 	int (*load)(unsigned, pgoff_t, struct page *, bool *); /* load a page */
 	void (*invalidate_page)(unsigned, pgoff_t); /* page no longer needed */
@@ -17,7 +19,8 @@ struct frontswap_ops {
 
 int frontswap_register_ops(const struct frontswap_ops *ops);
 
-extern void frontswap_init(unsigned type, unsigned long *map);
+extern void frontswap_init(unsigned type, unsigned long *map,
+			   struct block_device *bdev);
 extern int __frontswap_store(struct page *page);
 extern int __frontswap_load(struct page *page);
 extern void __frontswap_invalidate_page(unsigned, pgoff_t);
diff --git a/mm/frontswap.c b/mm/frontswap.c
index 2fb5df3384b8..967ce610a1de 100644
--- a/mm/frontswap.c
+++ b/mm/frontswap.c
@@ -107,7 +107,7 @@ int frontswap_register_ops(const struct frontswap_ops *ops)
 /*
  * Called when a swap device is swapon'd.
  */
-void frontswap_init(unsigned type, unsigned long *map)
+void frontswap_init(unsigned type, unsigned long *map, struct block_device *bdev)
 {
 	struct swap_info_struct *sis = swap_info[type];
 
@@ -128,7 +128,7 @@ void frontswap_init(unsigned type, unsigned long *map)
 
 	if (!frontswap_enabled())
 		return;
-	frontswap_ops->init(type);
+	frontswap_ops->init(type, bdev);
 }
 
 static bool __frontswap_test(struct swap_info_struct *sis,
diff --git a/mm/swapfile.c b/mm/swapfile.c
index a6945c2e0d03..a9424fd226bc 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2339,7 +2339,8 @@ static void enable_swap_info(struct swap_info_struct *p, int prio,
 				unsigned long *frontswap_map)
 {
 	if (IS_ENABLED(CONFIG_FRONTSWAP))
-		frontswap_init(p->type, frontswap_map);
+		frontswap_init(p->type, frontswap_map, p->bdev);
+
 	spin_lock(&swap_lock);
 	spin_lock(&p->lock);
 	setup_swap_info(p, prio, swap_map, cluster_info);
diff --git a/mm/zswap.c b/mm/zswap.c
index c122f042a49d..9247e3adc21f 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1510,7 +1510,7 @@ static void zswap_frontswap_invalidate_area(unsigned type)
 	zswap_trees[type] = NULL;
 }
 
-static void zswap_frontswap_init(unsigned type)
+static void zswap_frontswap_init(unsigned type, struct block_device *bdev)
 {
 	struct zswap_tree *tree;
 
-- 
2.41.0.255.g8b1d071c50-goog



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] zram: support frontswap
  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
  2023-07-11 10:08   ` Alexey Romanov
  2023-07-10 22:16 ` [PATCH 3/3] zram: remove swap_slot_free_notify Minchan Kim
  2023-07-11  5:17 ` [PATCH 0/3] zram: use frontswap for zram swap usecase Christoph Hellwig
  3 siblings, 1 reply; 10+ messages in thread
From: Minchan Kim @ 2023-07-10 22:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-mm, Jens Axboe, Konrad Rzeszutek Wilk, Seth Jennings,
	Sergey Senozhatsky, Minchan Kim

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



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] zram: remove swap_slot_free_notify
  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 ` [PATCH 2/3] zram: support frontswap Minchan Kim
@ 2023-07-10 22:16 ` 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
  3 siblings, 1 reply; 10+ messages in thread
From: Minchan Kim @ 2023-07-10 22:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-mm, Jens Axboe, Konrad Rzeszutek Wilk, Seth Jennings,
	Sergey Senozhatsky, Minchan Kim

Frontswap replaces the need for swap_slot_free_notify in block_device.
Therefore, we can remove it.

Signed-off-by: Minchan Kim <minchan@kernel.org>
---
 Documentation/filesystems/locking.rst |  5 -----
 drivers/block/zram/zram_drv.c         | 20 +-------------------
 include/linux/blkdev.h                |  2 --
 mm/swapfile.c                         |  8 --------
 4 files changed, 1 insertion(+), 34 deletions(-)

diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index aa1a233b0fa8..c94ef7d9fc6e 100644
--- a/Documentation/filesystems/locking.rst
+++ b/Documentation/filesystems/locking.rst
@@ -477,7 +477,6 @@ block_device_operations
 				unsigned long *);
 	void (*unlock_native_capacity) (struct gendisk *);
 	int (*getgeo)(struct block_device *, struct hd_geometry *);
-	void (*swap_slot_free_notify) (struct block_device *, unsigned long);
 
 locking rules:
 
@@ -491,12 +490,8 @@ compat_ioctl:		no
 direct_access:		no
 unlock_native_capacity:	no
 getgeo:			no
-swap_slot_free_notify:	no	(see below)
 ======================= ===================
 
-swap_slot_free_notify is called with swap_lock and sometimes the page lock
-held.
-
 
 file_operations
 ===============
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 5e973c982235..ec040ab3ab91 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1947,23 +1947,6 @@ static void zram_submit_bio(struct bio *bio)
 	}
 }
 
-static void zram_slot_free_notify(struct block_device *bdev,
-				unsigned long index)
-{
-	struct zram *zram;
-
-	zram = bdev->bd_disk->private_data;
-
-	atomic64_inc(&zram->stats.notify_free);
-	if (!zram_slot_trylock(zram, index)) {
-		atomic64_inc(&zram->stats.miss_free);
-		return;
-	}
-
-	zram_free_page(zram, index);
-	zram_slot_unlock(zram, index);
-}
-
 static void zram_destroy_comps(struct zram *zram)
 {
 	u32 prio;
@@ -2117,7 +2100,6 @@ static int zram_open(struct block_device *bdev, fmode_t mode)
 static const struct block_device_operations zram_devops = {
 	.open = zram_open,
 	.submit_bio = zram_submit_bio,
-	.swap_slot_free_notify = zram_slot_free_notify,
 	.owner = THIS_MODULE
 };
 
@@ -2206,7 +2188,7 @@ static int zram_frontswap_load(unsigned int type, pgoff_t index,
 
 	err = zram_read_from_zspool(zram, page, index);
 	if (!err)
-		zram_accessed(zram, index);
+		zram_free_page(zram, index);
 	zram_slot_unlock(zram, index);
 
 	return err;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index c0ffe203a602..49e1843e44ea 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1390,8 +1390,6 @@ struct block_device_operations {
 	int (*getgeo)(struct block_device *, struct hd_geometry *);
 	int (*set_read_only)(struct block_device *bdev, bool ro);
 	void (*free_disk)(struct gendisk *disk);
-	/* this callback is with swap_lock and sometimes page table lock held */
-	void (*swap_slot_free_notify) (struct block_device *, unsigned long);
 	int (*report_zones)(struct gendisk *, sector_t sector,
 			unsigned int nr_zones, report_zones_cb cb, void *data);
 	char *(*devnode)(struct gendisk *disk, umode_t *mode);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index a9424fd226bc..adc16d8883c8 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -726,7 +726,6 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
 {
 	unsigned long begin = offset;
 	unsigned long end = offset + nr_entries - 1;
-	void (*swap_slot_free_notify)(struct block_device *, unsigned long);
 
 	if (offset < si->lowest_bit)
 		si->lowest_bit = offset;
@@ -739,16 +738,9 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
 	}
 	atomic_long_add(nr_entries, &nr_swap_pages);
 	WRITE_ONCE(si->inuse_pages, si->inuse_pages - nr_entries);
-	if (si->flags & SWP_BLKDEV)
-		swap_slot_free_notify =
-			si->bdev->bd_disk->fops->swap_slot_free_notify;
-	else
-		swap_slot_free_notify = NULL;
 	while (offset <= end) {
 		arch_swap_invalidate_page(si->type, offset);
 		frontswap_invalidate_page(si->type, offset);
-		if (swap_slot_free_notify)
-			swap_slot_free_notify(si->bdev, offset);
 		offset++;
 	}
 	clear_shadow_from_swap_cache(si->type, begin, end);
-- 
2.41.0.255.g8b1d071c50-goog



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/3] zram: use frontswap for zram swap usecase
  2023-07-10 22:16 [PATCH 0/3] zram: use frontswap for zram swap usecase Minchan Kim
                   ` (2 preceding siblings ...)
  2023-07-10 22:16 ` [PATCH 3/3] zram: remove swap_slot_free_notify Minchan Kim
@ 2023-07-11  5:17 ` Christoph Hellwig
  2023-07-11 17:52   ` Nhat Pham
  3 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2023-07-11  5:17 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Andrew Morton, linux-mm, Jens Axboe, Konrad Rzeszutek Wilk,
	Seth Jennings, Sergey Senozhatsky

On Mon, Jul 10, 2023 at 03:16:56PM -0700, Minchan Kim wrote:
> This patchset uses frontswap for zram swap usecase and remove
> swap_slot_free_notify swap specific operation in block device.
> It shows 13% swapout improvement for MADV_PAGEOUT.

Err, no.  frontswap needs to go away, and not be tried to a block
driver.  If you want compressed swap without a block driver please use
zswap and help improvig it and the swap abstraction to not require
a backing allocation for it.

We need to fix swap and not pile hacks on top of hacks.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] zram: support frontswap
  2023-07-10 22:16 ` [PATCH 2/3] zram: support frontswap Minchan Kim
@ 2023-07-11 10:08   ` Alexey Romanov
  2023-07-11 23:58     ` Minchan Kim
  0 siblings, 1 reply; 10+ messages in thread
From: Alexey Romanov @ 2023-07-11 10:08 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Andrew Morton, linux-mm, Jens Axboe, Konrad Rzeszutek Wilk,
	Seth Jennings, Sergey Senozhatsky

Hello,

On Mon, Jul 10, 2023 at 03:16:58PM -0700, Minchan Kim wrote:
> 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);

Looks like zram_slot_unlock should be here instead of zram_slot_lock.

> +		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;
> +}

It makes sense? Maybe we just leave this function empty?

> +
> +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
> 
> 

-- 
Thank you,
Alexey

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] zram: remove swap_slot_free_notify
  2023-07-10 22:16 ` [PATCH 3/3] zram: remove swap_slot_free_notify Minchan Kim
@ 2023-07-11 10:09   ` Alexey Romanov
  0 siblings, 0 replies; 10+ messages in thread
From: Alexey Romanov @ 2023-07-11 10:09 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Andrew Morton, linux-mm, Jens Axboe, Konrad Rzeszutek Wilk,
	Seth Jennings, Sergey Senozhatsky

Hello,

On Mon, Jul 10, 2023 at 03:16:59PM -0700, Minchan Kim wrote:
> Frontswap replaces the need for swap_slot_free_notify in block_device.
> Therefore, we can remove it.
> 
> Signed-off-by: Minchan Kim <minchan@kernel.org>
> ---
>  Documentation/filesystems/locking.rst |  5 -----
>  drivers/block/zram/zram_drv.c         | 20 +-------------------
>  include/linux/blkdev.h                |  2 --
>  mm/swapfile.c                         |  8 --------
>  4 files changed, 1 insertion(+), 34 deletions(-)
> 
> diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
> index aa1a233b0fa8..c94ef7d9fc6e 100644
> --- a/Documentation/filesystems/locking.rst
> +++ b/Documentation/filesystems/locking.rst
> @@ -477,7 +477,6 @@ block_device_operations
>  				unsigned long *);
>  	void (*unlock_native_capacity) (struct gendisk *);
>  	int (*getgeo)(struct block_device *, struct hd_geometry *);
> -	void (*swap_slot_free_notify) (struct block_device *, unsigned long);
>  
>  locking rules:
>  
> @@ -491,12 +490,8 @@ compat_ioctl:		no
>  direct_access:		no
>  unlock_native_capacity:	no
>  getgeo:			no
> -swap_slot_free_notify:	no	(see below)
>  ======================= ===================
>  
> -swap_slot_free_notify is called with swap_lock and sometimes the page lock
> -held.
> -
>  
>  file_operations
>  ===============
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index 5e973c982235..ec040ab3ab91 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -1947,23 +1947,6 @@ static void zram_submit_bio(struct bio *bio)
>  	}
>  }
>  
> -static void zram_slot_free_notify(struct block_device *bdev,
> -				unsigned long index)
> -{
> -	struct zram *zram;
> -
> -	zram = bdev->bd_disk->private_data;
> -
> -	atomic64_inc(&zram->stats.notify_free);
> -	if (!zram_slot_trylock(zram, index)) {
> -		atomic64_inc(&zram->stats.miss_free);
> -		return;
> -	}
> -
> -	zram_free_page(zram, index);
> -	zram_slot_unlock(zram, index);
> -}
> -
>  static void zram_destroy_comps(struct zram *zram)
>  {
>  	u32 prio;
> @@ -2117,7 +2100,6 @@ static int zram_open(struct block_device *bdev, fmode_t mode)
>  static const struct block_device_operations zram_devops = {
>  	.open = zram_open,
>  	.submit_bio = zram_submit_bio,
> -	.swap_slot_free_notify = zram_slot_free_notify,
>  	.owner = THIS_MODULE
>  };
>  
> @@ -2206,7 +2188,7 @@ static int zram_frontswap_load(unsigned int type, pgoff_t index,
>  
>  	err = zram_read_from_zspool(zram, page, index);
>  	if (!err)
> -		zram_accessed(zram, index);
> +		zram_free_page(zram, index);

Probably it should be in the previous commit.

>  	zram_slot_unlock(zram, index);
>  
>  	return err;
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index c0ffe203a602..49e1843e44ea 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -1390,8 +1390,6 @@ struct block_device_operations {
>  	int (*getgeo)(struct block_device *, struct hd_geometry *);
>  	int (*set_read_only)(struct block_device *bdev, bool ro);
>  	void (*free_disk)(struct gendisk *disk);
> -	/* this callback is with swap_lock and sometimes page table lock held */
> -	void (*swap_slot_free_notify) (struct block_device *, unsigned long);
>  	int (*report_zones)(struct gendisk *, sector_t sector,
>  			unsigned int nr_zones, report_zones_cb cb, void *data);
>  	char *(*devnode)(struct gendisk *disk, umode_t *mode);
> diff --git a/mm/swapfile.c b/mm/swapfile.c
> index a9424fd226bc..adc16d8883c8 100644
> --- a/mm/swapfile.c
> +++ b/mm/swapfile.c
> @@ -726,7 +726,6 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
>  {
>  	unsigned long begin = offset;
>  	unsigned long end = offset + nr_entries - 1;
> -	void (*swap_slot_free_notify)(struct block_device *, unsigned long);
>  
>  	if (offset < si->lowest_bit)
>  		si->lowest_bit = offset;
> @@ -739,16 +738,9 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
>  	}
>  	atomic_long_add(nr_entries, &nr_swap_pages);
>  	WRITE_ONCE(si->inuse_pages, si->inuse_pages - nr_entries);
> -	if (si->flags & SWP_BLKDEV)
> -		swap_slot_free_notify =
> -			si->bdev->bd_disk->fops->swap_slot_free_notify;
> -	else
> -		swap_slot_free_notify = NULL;
>  	while (offset <= end) {
>  		arch_swap_invalidate_page(si->type, offset);
>  		frontswap_invalidate_page(si->type, offset);
> -		if (swap_slot_free_notify)
> -			swap_slot_free_notify(si->bdev, offset);
>  		offset++;
>  	}
>  	clear_shadow_from_swap_cache(si->type, begin, end);
> -- 
> 2.41.0.255.g8b1d071c50-goog
> 
> 

-- 
Thank you,
Alexey

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/3] zram: use frontswap for zram swap usecase
  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
  0 siblings, 1 reply; 10+ messages in thread
From: Nhat Pham @ 2023-07-11 17:52 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minchan Kim, Andrew Morton, linux-mm, Jens Axboe,
	Konrad Rzeszutek Wilk, Seth Jennings, Sergey Senozhatsky

On Mon, Jul 10, 2023 at 10:18 PM Christoph Hellwig <hch@infradead.org> wrote:
>
> On Mon, Jul 10, 2023 at 03:16:56PM -0700, Minchan Kim wrote:
> > This patchset uses frontswap for zram swap usecase and remove
> > swap_slot_free_notify swap specific operation in block device.
> > It shows 13% swapout improvement for MADV_PAGEOUT.
>
> Err, no.  frontswap needs to go away, and not be tried to a block
> driver.  If you want compressed swap without a block driver please use
> zswap and help improvig it and the swap abstraction to not require
> a backing allocation for it.
>
> We need to fix swap and not pile hacks on top of hacks.
>

+1. Based on earlier discussions, it seems like the agreed upon way forward
is to remove the frontswap interface:

https://lore.kernel.org/linux-mm/20230530235447.GB102494@cmpxchg.org/


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/3] zram: use frontswap for zram swap usecase
  2023-07-11 17:52   ` Nhat Pham
@ 2023-07-11 23:56     ` Minchan Kim
  0 siblings, 0 replies; 10+ messages in thread
From: Minchan Kim @ 2023-07-11 23:56 UTC (permalink / raw)
  To: Nhat Pham
  Cc: Christoph Hellwig, Andrew Morton, linux-mm, Jens Axboe,
	Konrad Rzeszutek Wilk, Seth Jennings, Sergey Senozhatsky

On Tue, Jul 11, 2023 at 10:52:02AM -0700, Nhat Pham wrote:
> On Mon, Jul 10, 2023 at 10:18 PM Christoph Hellwig <hch@infradead.org> wrote:
> >
> > On Mon, Jul 10, 2023 at 03:16:56PM -0700, Minchan Kim wrote:
> > > This patchset uses frontswap for zram swap usecase and remove
> > > swap_slot_free_notify swap specific operation in block device.
> > > It shows 13% swapout improvement for MADV_PAGEOUT.
> >
> > Err, no.  frontswap needs to go away, and not be tried to a block
> > driver.  If you want compressed swap without a block driver please use
> > zswap and help improvig it and the swap abstraction to not require
> > a backing allocation for it.
> >
> > We need to fix swap and not pile hacks on top of hacks.
> >
> 
> +1. Based on earlier discussions, it seems like the agreed upon way forward
> is to remove the frontswap interface:
> 
> https://lore.kernel.org/linux-mm/20230530235447.GB102494@cmpxchg.org/

Thanks for feedback.

Understood. I also agree frontswap is hack so let me this patchset.
I hope swap abstraction goes to the way Chris Li suggested in the end.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] zram: support frontswap
  2023-07-11 10:08   ` Alexey Romanov
@ 2023-07-11 23:58     ` Minchan Kim
  0 siblings, 0 replies; 10+ messages in thread
From: Minchan Kim @ 2023-07-11 23:58 UTC (permalink / raw)
  To: Alexey Romanov
  Cc: Andrew Morton, linux-mm, Jens Axboe, Konrad Rzeszutek Wilk,
	Seth Jennings, Sergey Senozhatsky

On Tue, Jul 11, 2023 at 10:08:46AM +0000, Alexey Romanov wrote:
> Hello,
> 
> On Mon, Jul 10, 2023 at 03:16:58PM -0700, Minchan Kim wrote:
> > 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);
> 
> Looks like zram_slot_unlock should be here instead of zram_slot_lock.

me/ slabs self.

> 
> > +		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;
> > +}
> 
> It makes sense? Maybe we just leave this function empty?

Sorry, it was wrong version from my git tree.
I had destroy zram in the case originally
but since I decide to drop this patchset, never mind.

Thanks for spending time for review, Alexey.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-07-11 23:58 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 2/3] zram: support frontswap Minchan Kim
2023-07-11 10:08   ` 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

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.