The size of biovec's memory of one dm_io_client will be reserved_bio_based_ios(default value is 16) * 4KiB memory. When the number of dm-bufio(dm-verity) devices is dozens, the total memory size will be several MiBs.
The number of dm-bufio(dm-verity) devices is 59 on my test device, and the size of biovec's memory here will be 3.87MiB. This commit will reduce the memory usage of dm-bufio by making all dm_bufio_client share the same dm_io_client. Fixes: 95d402f057f2e ("dm: add bufio") Signed-off-by: LongPing Wei <weilongp...@oppo.com> --- drivers/md/dm-bufio.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index f0b5a6931161..5aa53b06112d 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -70,6 +70,8 @@ #define SCAN_RESCHED_CYCLE 16 +static struct dm_io_client *bufio_io_client; + /*--------------------------------------------------------------*/ /* @@ -992,7 +994,6 @@ struct dm_bufio_client { void (*write_callback)(struct dm_buffer *buf); struct kmem_cache *slab_buffer; struct kmem_cache *slab_cache; - struct dm_io_client *dm_io; struct list_head reserved_buffers; unsigned int need_reserved_buffers; @@ -1311,7 +1312,7 @@ static void use_dmio(struct dm_buffer *b, enum req_op op, sector_t sector, .bi_opf = op, .notify.fn = dmio_complete, .notify.context = b, - .client = b->c->dm_io, + .client = bufio_io_client, }; struct dm_io_region region = { .bdev = b->c->bdev, @@ -2197,7 +2198,7 @@ int dm_bufio_issue_flush(struct dm_bufio_client *c) .bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC, .mem.type = DM_IO_KMEM, .mem.ptr.addr = NULL, - .client = c->dm_io, + .client = bufio_io_client, }; struct dm_io_region io_reg = { .bdev = c->bdev, @@ -2221,7 +2222,7 @@ int dm_bufio_issue_discard(struct dm_bufio_client *c, sector_t block, sector_t c .bi_opf = REQ_OP_DISCARD | REQ_SYNC, .mem.type = DM_IO_KMEM, .mem.ptr.addr = NULL, - .client = c->dm_io, + .client = bufio_io_client, }; struct dm_io_region io_reg = { .bdev = c->bdev, @@ -2310,7 +2311,7 @@ EXPORT_SYMBOL_GPL(dm_bufio_get_device_size); struct dm_io_client *dm_bufio_get_dm_io_client(struct dm_bufio_client *c) { - return c->dm_io; + return bufio_io_client; } EXPORT_SYMBOL_GPL(dm_bufio_get_dm_io_client); @@ -2530,12 +2531,6 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign init_waitqueue_head(&c->free_buffer_wait); c->async_write_error = 0; - c->dm_io = dm_io_client_create(); - if (IS_ERR(c->dm_io)) { - r = PTR_ERR(c->dm_io); - goto bad_dm_io; - } - if (block_size <= KMALLOC_MAX_SIZE && !is_power_of_2(block_size)) { unsigned int align = min(1U << __ffs(block_size), (unsigned int)PAGE_SIZE); @@ -2606,8 +2601,6 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign } kmem_cache_destroy(c->slab_cache); kmem_cache_destroy(c->slab_buffer); - dm_io_client_destroy(c->dm_io); -bad_dm_io: mutex_destroy(&c->lock); if (c->no_sleep) static_branch_dec(&no_sleep_enabled); @@ -2657,7 +2650,6 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c) cache_destroy(&c->cache); kmem_cache_destroy(c->slab_cache); kmem_cache_destroy(c->slab_buffer); - dm_io_client_destroy(c->dm_io); mutex_destroy(&c->lock); if (c->no_sleep) static_branch_dec(&no_sleep_enabled); @@ -2944,6 +2936,15 @@ static int __init dm_bufio_init(void) if (!dm_bufio_wq) return -ENOMEM; + bufio_io_client = dm_io_client_create(); + if (IS_ERR(bufio_io_client)) { + int r = PTR_ERR(bufio_io_client); + bufio_io_client = NULL; + DMERR("Cannot allocate dm io"); + destroy_workqueue(dm_bufio_wq); + return r; + } + INIT_DELAYED_WORK(&dm_bufio_cleanup_old_work, work_fn); INIT_WORK(&dm_bufio_replacement_work, do_global_cleanup); queue_delayed_work(dm_bufio_wq, &dm_bufio_cleanup_old_work, -- 2.34.1