zram: add writeback batch size device attr

Introduce writeback_batch_size device attribute so that the maximum number
of in-flight writeback bio requests can be configured at run-time
per-device.  This essentially enables batched bio writeback.

Link: https://lkml.kernel.org/r/20251122074029.3948921-3-senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Brian Geffon <bgeffon@google.com>
Cc: Minchan Kim <minchan@google.com>
Cc: Richard Chang <richardycc@google.com>
Cc: Yuwen Chen <ywen.chen@foxmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Sergey Senozhatsky 2025-11-22 16:40:25 +09:00 committed by Andrew Morton
parent f405066a1f
commit e828cccb72
2 changed files with 41 additions and 6 deletions

View File

@ -590,6 +590,40 @@ static ssize_t writeback_limit_show(struct device *dev,
return sysfs_emit(buf, "%llu\n", val); return sysfs_emit(buf, "%llu\n", val);
} }
static ssize_t writeback_batch_size_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct zram *zram = dev_to_zram(dev);
u32 val;
if (kstrtouint(buf, 10, &val))
return -EINVAL;
if (!val)
return -EINVAL;
down_write(&zram->init_lock);
zram->wb_batch_size = val;
up_write(&zram->init_lock);
return len;
}
static ssize_t writeback_batch_size_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
u32 val;
struct zram *zram = dev_to_zram(dev);
down_read(&zram->init_lock);
val = zram->wb_batch_size;
up_read(&zram->init_lock);
return sysfs_emit(buf, "%u\n", val);
}
static void reset_bdev(struct zram *zram) static void reset_bdev(struct zram *zram)
{ {
if (!zram->backing_dev) if (!zram->backing_dev)
@ -781,10 +815,7 @@ static void release_wb_ctl(struct zram_wb_ctl *wb_ctl)
kfree(wb_ctl); kfree(wb_ctl);
} }
/* XXX: should be a per-device sysfs attr */ static struct zram_wb_ctl *init_wb_ctl(struct zram *zram)
#define ZRAM_WB_REQ_CNT 32
static struct zram_wb_ctl *init_wb_ctl(void)
{ {
struct zram_wb_ctl *wb_ctl; struct zram_wb_ctl *wb_ctl;
int i; int i;
@ -799,7 +830,7 @@ static struct zram_wb_ctl *init_wb_ctl(void)
init_waitqueue_head(&wb_ctl->done_wait); init_waitqueue_head(&wb_ctl->done_wait);
spin_lock_init(&wb_ctl->done_lock); spin_lock_init(&wb_ctl->done_lock);
for (i = 0; i < ZRAM_WB_REQ_CNT; i++) { for (i = 0; i < zram->wb_batch_size; i++) {
struct zram_wb_req *req; struct zram_wb_req *req;
/* /*
@ -1200,7 +1231,7 @@ static ssize_t writeback_store(struct device *dev,
goto release_init_lock; goto release_init_lock;
} }
wb_ctl = init_wb_ctl(); wb_ctl = init_wb_ctl(zram);
if (!wb_ctl) { if (!wb_ctl) {
ret = -ENOMEM; ret = -ENOMEM;
goto release_init_lock; goto release_init_lock;
@ -2843,6 +2874,7 @@ static DEVICE_ATTR_RW(backing_dev);
static DEVICE_ATTR_WO(writeback); static DEVICE_ATTR_WO(writeback);
static DEVICE_ATTR_RW(writeback_limit); static DEVICE_ATTR_RW(writeback_limit);
static DEVICE_ATTR_RW(writeback_limit_enable); static DEVICE_ATTR_RW(writeback_limit_enable);
static DEVICE_ATTR_RW(writeback_batch_size);
#endif #endif
#ifdef CONFIG_ZRAM_MULTI_COMP #ifdef CONFIG_ZRAM_MULTI_COMP
static DEVICE_ATTR_RW(recomp_algorithm); static DEVICE_ATTR_RW(recomp_algorithm);
@ -2864,6 +2896,7 @@ static struct attribute *zram_disk_attrs[] = {
&dev_attr_writeback.attr, &dev_attr_writeback.attr,
&dev_attr_writeback_limit.attr, &dev_attr_writeback_limit.attr,
&dev_attr_writeback_limit_enable.attr, &dev_attr_writeback_limit_enable.attr,
&dev_attr_writeback_batch_size.attr,
#endif #endif
&dev_attr_io_stat.attr, &dev_attr_io_stat.attr,
&dev_attr_mm_stat.attr, &dev_attr_mm_stat.attr,
@ -2925,6 +2958,7 @@ static int zram_add(void)
init_rwsem(&zram->init_lock); init_rwsem(&zram->init_lock);
#ifdef CONFIG_ZRAM_WRITEBACK #ifdef CONFIG_ZRAM_WRITEBACK
zram->wb_batch_size = 32;
spin_lock_init(&zram->wb_limit_lock); spin_lock_init(&zram->wb_limit_lock);
#endif #endif

View File

@ -129,6 +129,7 @@ struct zram {
struct file *backing_dev; struct file *backing_dev;
spinlock_t wb_limit_lock; spinlock_t wb_limit_lock;
bool wb_limit_enable; bool wb_limit_enable;
u32 wb_batch_size;
u64 bd_wb_limit; u64 bd_wb_limit;
struct block_device *bdev; struct block_device *bdev;
unsigned long *bitmap; unsigned long *bitmap;