The patch titled Subject: zram: writeback throttle has been added to the -mm tree. Its filename is zram-writeback-throttle.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/zram-writeback-throttle.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/zram-writeback-throttle.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Minchan Kim <minchan@xxxxxxxxxx> Subject: zram: writeback throttle On small memory systems there are lots of write IOs so if we use a flash device as swap there would be serious flash wearout. To overcome this problem, system developers need to design a write limitation strategy to guarantee flash health for the entire product life. This patch creates a new knob "writeback_limit" on zram. With that, if the current writeback IO count (/sys/block/zramX/io_stat) exceeds the limitation, zram stops further writeback until the admin can reset the limit. Link: http://lkml.kernel.org/r/20181127055429.251614-8-minchan@xxxxxxxxxx Signed-off-by: Minchan Kim <minchan@xxxxxxxxxx> Cc: Joey Pabalinas <joeypabalinas@xxxxxxxxx> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@xxxxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> [4.14+] Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- Documentation/ABI/testing/sysfs-block-zram | 9 +++ Documentation/blockdev/zram.txt | 2 drivers/block/zram/zram_drv.c | 47 ++++++++++++++++++- drivers/block/zram/zram_drv.h | 2 4 files changed, 59 insertions(+), 1 deletion(-) --- a/Documentation/ABI/testing/sysfs-block-zram~zram-writeback-throttle +++ a/Documentation/ABI/testing/sysfs-block-zram @@ -121,3 +121,12 @@ Description: The bd_stat file is read-only and represents backing device's statistics (bd_count, bd_reads, bd_writes) in a format similar to block layer statistics file format. + +What: /sys/block/zram<id>/writeback_limit +Date: November 2018 +Contact: Minchan Kim <minchan@xxxxxxxxxx> +Description: + The writeback_limit file is read-write and specifies the maximum + amount of writeback ZRAM can do. The limit could be changed + in run time and "0" means disable the limit. + No limit is the initial state. --- a/Documentation/blockdev/zram.txt~zram-writeback-throttle +++ a/Documentation/blockdev/zram.txt @@ -164,6 +164,8 @@ reset WO trigger device r mem_used_max WO reset the `mem_used_max' counter (see later) mem_limit WO specifies the maximum amount of memory ZRAM can use to store the compressed data +writeback_limit WO specifies the maximum amount of write IO zram can + write out to backing device as 4KB unit max_comp_streams RW the number of possible concurrent compress operations comp_algorithm RW show and change the compression algorithm compact WO trigger memory compaction --- a/drivers/block/zram/zram_drv.c~zram-writeback-throttle +++ a/drivers/block/zram/zram_drv.c @@ -330,6 +330,40 @@ next: } #ifdef CONFIG_ZRAM_WRITEBACK + +static ssize_t writeback_limit_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct zram *zram = dev_to_zram(dev); + u64 val; + ssize_t ret = -EINVAL; + + if (kstrtoull(buf, 10, &val)) + return ret; + + down_read(&zram->init_lock); + atomic64_set(&zram->stats.bd_wb_limit, val); + if (val == 0 || val > atomic64_read(&zram->stats.bd_writes)) + zram->stop_writeback = false; + up_read(&zram->init_lock); + ret = len; + + return ret; +} + +static ssize_t writeback_limit_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u64 val; + struct zram *zram = dev_to_zram(dev); + + down_read(&zram->init_lock); + val = atomic64_read(&zram->stats.bd_wb_limit); + up_read(&zram->init_lock); + + return scnprintf(buf, PAGE_SIZE, "%llu\n", val); +} + static void reset_bdev(struct zram *zram) { struct block_device *bdev; @@ -571,6 +605,7 @@ static ssize_t writeback_store(struct de char mode_buf[8]; unsigned long mode = -1UL; unsigned long blk_idx = 0; + u64 wb_count, wb_limit; sz = strscpy(mode_buf, buf, sizeof(mode_buf)); if (sz <= 0) @@ -612,6 +647,11 @@ static ssize_t writeback_store(struct de bvec.bv_len = PAGE_SIZE; bvec.bv_offset = 0; + if (zram->stop_writeback) { + ret = -EIO; + break; + } + if (!blk_idx) { blk_idx = alloc_block_bdev(zram); if (!blk_idx) { @@ -670,7 +710,7 @@ static ssize_t writeback_store(struct de continue; } - atomic64_inc(&zram->stats.bd_writes); + wb_count = atomic64_inc_return(&zram->stats.bd_writes); /* * We released zram_slot_lock so need to check if the slot was * changed. If there is freeing for the slot, we can catch it @@ -694,6 +734,9 @@ static ssize_t writeback_store(struct de zram_set_element(zram, index, blk_idx); blk_idx = 0; atomic64_inc(&zram->stats.pages_stored); + wb_limit = atomic64_read(&zram->stats.bd_wb_limit); + if (wb_limit != 0 && wb_count >= wb_limit) + zram->stop_writeback = true; next: zram_slot_unlock(zram, index); } @@ -1767,6 +1810,7 @@ static DEVICE_ATTR_RW(comp_algorithm); #ifdef CONFIG_ZRAM_WRITEBACK static DEVICE_ATTR_RW(backing_dev); static DEVICE_ATTR_WO(writeback); +static DEVICE_ATTR_RW(writeback_limit); #endif static struct attribute *zram_disk_attrs[] = { @@ -1782,6 +1826,7 @@ static struct attribute *zram_disk_attrs #ifdef CONFIG_ZRAM_WRITEBACK &dev_attr_backing_dev.attr, &dev_attr_writeback.attr, + &dev_attr_writeback_limit.attr, #endif &dev_attr_io_stat.attr, &dev_attr_mm_stat.attr, --- a/drivers/block/zram/zram_drv.h~zram-writeback-throttle +++ a/drivers/block/zram/zram_drv.h @@ -86,6 +86,7 @@ struct zram_stats { atomic64_t bd_count; /* no. of pages in backing device */ atomic64_t bd_reads; /* no. of reads from backing device */ atomic64_t bd_writes; /* no. of writes from backing device */ + atomic64_t bd_wb_limit; /* writeback limit of backing device */ #endif }; @@ -113,6 +114,7 @@ struct zram { */ bool claim; /* Protected by bdev->bd_mutex */ struct file *backing_dev; + bool stop_writeback; #ifdef CONFIG_ZRAM_WRITEBACK struct block_device *bdev; unsigned int old_block_size; _ Patches currently in -mm which might be from minchan@xxxxxxxxxx are zram-fix-lockdep-warning-of-free-block-handling.patch zram-fix-double-free-backing-device.patch zram-refactoring-flags-and-writeback-stuff.patch zram-introduce-zram_idle-flag.patch zram-support-idle-huge-page-writeback.patch zram-add-bd_stat-statistics.patch zram-writeback-throttle.patch