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-verity devices is dozens, the total memory size will be several MiBs.
The number of 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-verity by making all verity devices share the same dm_io_client and recheck_pool. Fixes: 9177f3c0dea61 ("dm-verity: recheck the hash after a failure") Signed-off-by: LongPing Wei <weilongp...@oppo.com> --- drivers/md/dm-verity-target.c | 71 ++++++++++++++++++++++++----------- drivers/md/dm-verity.h | 3 -- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 3c427f18a04b..986c3386aa59 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -72,6 +72,9 @@ struct dm_verity_prefetch_work { unsigned int n_blocks; }; +static struct dm_io_client *verity_io_client; +static mempool_t verity_recheck_pool; + /* * Auxiliary structure appended to each dm-bufio buffer. If the value * hash_verified is nonzero, hash of the block has been verified. @@ -449,14 +452,14 @@ static noinline int verity_recheck(struct dm_verity *v, struct dm_verity_io *io, struct dm_io_request io_req; struct dm_io_region io_loc; - page = mempool_alloc(&v->recheck_pool, GFP_NOIO); + page = mempool_alloc(&verity_recheck_pool, GFP_NOIO); buffer = page_to_virt(page); io_req.bi_opf = REQ_OP_READ; io_req.mem.type = DM_IO_KMEM; io_req.mem.ptr.addr = buffer; io_req.notify.fn = NULL; - io_req.client = v->io; + io_req.client = verity_io_client; io_loc.bdev = v->data_dev->bdev; io_loc.sector = cur_block << (v->data_dev_block_bits - SECTOR_SHIFT); io_loc.count = 1 << (v->data_dev_block_bits - SECTOR_SHIFT); @@ -478,7 +481,7 @@ static noinline int verity_recheck(struct dm_verity *v, struct dm_verity_io *io, memcpy(dest, buffer, 1 << v->data_dev_block_bits); r = 0; free_ret: - mempool_free(page, &v->recheck_pool); + mempool_free(page, &verity_recheck_pool); return r; } @@ -1075,10 +1078,6 @@ static void verity_dtr(struct dm_target *ti) if (v->verify_wq) destroy_workqueue(v->verify_wq); - mempool_exit(&v->recheck_pool); - if (v->io) - dm_io_client_destroy(v->io); - if (v->bufio) dm_bufio_client_destroy(v->bufio); @@ -1625,20 +1624,6 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv) } v->hash_blocks = hash_position; - r = mempool_init_page_pool(&v->recheck_pool, 1, 0); - if (unlikely(r)) { - ti->error = "Cannot allocate mempool"; - goto bad; - } - - v->io = dm_io_client_create(); - if (IS_ERR(v->io)) { - r = PTR_ERR(v->io); - v->io = NULL; - ti->error = "Cannot allocate dm io"; - goto bad; - } - v->bufio = dm_bufio_client_create(v->hash_dev->bdev, 1 << v->hash_dev_block_bits, 1, sizeof(struct buffer_aux), dm_bufio_alloc_callback, NULL, @@ -1822,7 +1807,49 @@ static struct target_type verity_target = { .preresume = verity_preresume, #endif /* CONFIG_SECURITY */ }; -module_dm(verity); + +static int __init dm_verity_init(void) +{ + int r; + + r = mempool_init_page_pool(&verity_recheck_pool, 1, 0); + if (unlikely(r)) { + DMERR("Cannot allocate mempool"); + goto mempool_init_page_pool_failed; + } + + verity_io_client = dm_io_client_create(); + if (IS_ERR(verity_io_client)) { + r = PTR_ERR(verity_io_client); + verity_io_client = NULL; + DMERR("Cannot allocate dm io"); + goto dm_io_client_create_failed; + } + + r = dm_register_target(&(verity_target)); + if (unlikely(r)) + goto dm_register_target_failed; + return r; + +dm_register_target_failed: + dm_io_client_destroy(verity_io_client); + verity_io_client = NULL; +dm_io_client_create_failed: + mempool_exit(&verity_recheck_pool); +mempool_init_page_pool_failed: + return r; +} +module_init(dm_verity_init); + +static void __exit dm_verity_exit(void) +{ + dm_unregister_target(&(verity_target)); + mempool_exit(&verity_recheck_pool); + if (verity_io_client) + dm_io_client_destroy(verity_io_client); + verity_io_client = NULL; +} +module_exit(dm_verity_exit) /* * Check whether a DM target is a verity target. diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h index 8cbb57862ae1..f28454f81249 100644 --- a/drivers/md/dm-verity.h +++ b/drivers/md/dm-verity.h @@ -75,9 +75,6 @@ struct dm_verity { unsigned long *validated_blocks; /* bitset blocks validated */ char *signature_key_desc; /* signature keyring reference */ - - struct dm_io_client *io; - mempool_t recheck_pool; }; struct dm_verity_io { -- 2.34.1