Commit 94541bc3 authored by Brian Geffon's avatar Brian Geffon Committed by Andrew Morton
Browse files

zram: always expose rw_page

Currently zram will adjust its fops to a version which does not contain
rw_page when a backing device has been assigned.  This is done to prevent
upper layers from assuming a synchronous operation when a page may have
been written back.  This forces every operation through bio which has
overhead associated with bio_alloc/frees.

The code can be simplified to always expose an rw_page method and only in
the rare event that a page is written back we instead will return
-EOPNOTSUPP forcing the upper layer to fallback to bio.

Link: https://lkml.kernel.org/r/20221003144832.2906610-1-bgeffon@google.com


Signed-off-by: default avatarBrian Geffon <bgeffon@google.com>
Reviewed-by: default avatarSergey Senozhatsky <senozhatsky@chromium.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Rom Lemarchand <romlem@google.com>
Cc: Suleiman Souhlal <suleiman@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 14c2ac36
Loading
Loading
Loading
Loading
+3 −23
Original line number Diff line number Diff line
@@ -52,9 +52,6 @@ static unsigned int num_devices = 1;
static size_t huge_class_size;

static const struct block_device_operations zram_devops;
#ifdef CONFIG_ZRAM_WRITEBACK
static const struct block_device_operations zram_wb_devops;
#endif

static void zram_free_page(struct zram *zram, size_t index);
static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
@@ -546,17 +543,6 @@ static ssize_t backing_dev_store(struct device *dev,
	zram->backing_dev = backing_dev;
	zram->bitmap = bitmap;
	zram->nr_pages = nr_pages;
	/*
	 * With writeback feature, zram does asynchronous IO so it's no longer
	 * synchronous device so let's remove synchronous io flag. Othewise,
	 * upper layer(e.g., swap) could wait IO completion rather than
	 * (submit and return), which will cause system sluggish.
	 * Furthermore, when the IO function returns(e.g., swap_readpage),
	 * upper layer expects IO was done so it could deallocate the page
	 * freely but in fact, IO is going on so finally could cause
	 * use-after-free when the IO is really done.
	 */
	zram->disk->fops = &zram_wb_devops;
	up_write(&zram->init_lock);

	pr_info("setup backing device %s\n", file_name);
@@ -1270,6 +1256,9 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index,
		struct bio_vec bvec;

		zram_slot_unlock(zram, index);
		/* A null bio means rw_page was used, we must fallback to bio */
		if (!bio)
			return -EOPNOTSUPP;

		bvec.bv_page = page;
		bvec.bv_len = PAGE_SIZE;
@@ -1856,15 +1845,6 @@ static const struct block_device_operations zram_devops = {
	.owner = THIS_MODULE
};

#ifdef CONFIG_ZRAM_WRITEBACK
static const struct block_device_operations zram_wb_devops = {
	.open = zram_open,
	.submit_bio = zram_submit_bio,
	.swap_slot_free_notify = zram_slot_free_notify,
	.owner = THIS_MODULE
};
#endif

static DEVICE_ATTR_WO(compact);
static DEVICE_ATTR_RW(disksize);
static DEVICE_ATTR_RO(initstate);