| From: Brian Geffon <bgeffon@google.com> |
| Subject: zram: always expose rw_page |
| Date: Mon, 3 Oct 2022 10:48:32 -0400 |
| |
| 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: Brian Geffon <bgeffon@google.com> |
| Reviewed-by: Sergey 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: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| drivers/block/zram/zram_drv.c | 26 +++----------------------- |
| 1 file changed, 3 insertions(+), 23 deletions(-) |
| |
| --- a/drivers/block/zram/zram_drv.c~zram-always-expose-rw_page |
| +++ a/drivers/block/zram/zram_drv.c |
| @@ -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 |
| 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 |
| 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_operati |
| .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); |
| _ |