[Devel] [PATCH RHEL8 COMMIT] dm-ploop: Introduce memcache for prq

Konstantin Khorenko khorenko at virtuozzo.com
Thu Aug 26 16:27:29 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-305.3.1.vz8.7.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-305.3.1.vz8.7.10
------>
commit 9389302949eaf7ac7e78d6d57391dcfee061f9ca
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Thu Aug 26 16:27:29 2021 +0300

    dm-ploop: Introduce memcache for prq
    
    kmalloc(GFP_ATOMIC) is not good for ploop_clone_and_map(),
    since it may meet ENOMEM, and request will fail.
    
    To avoid this, we introduce memcache, which contains
    number of elements equal to max number of requests.
    Thus, the allocation will never fail.
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-ploop-map.c    |  4 ++--
 drivers/md/dm-ploop-target.c | 14 +++++++++++---
 drivers/md/dm-ploop.h        |  2 ++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 9a49867e4800..a3f63c238198 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -198,7 +198,7 @@ static void prq_endio(struct pio *pio, void *prq_ptr, blk_status_t bi_status)
 			return;
 	}
 
-	kfree(prq);
+	mempool_free(prq, pio->ploop->prq_pool);
 	dm_complete_request(rq, bi_status);
 }
 
@@ -1888,7 +1888,7 @@ int ploop_clone_and_map(struct dm_target *ti, struct request *rq,
 	if (blk_rq_bytes(rq) && ploop_rq_valid(ploop, rq) < 0)
 		return DM_MAPIO_KILL;
 
-	prq = kmalloc(sizeof(*prq) + sizeof(*pio), GFP_ATOMIC); /* TODO: memcache */
+	prq = mempool_alloc(ploop->prq_pool, GFP_ATOMIC);
 	if (!prq)
 		return DM_MAPIO_KILL;
 	pio = (void *)prq + sizeof(*prq);
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 94442597c839..ec0efddef2ac 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -27,6 +27,7 @@ module_param(ignore_signature_disk_in_use, bool, 0444);
 MODULE_PARM_DESC(ignore_signature_disk_in_use,
                 "Does not check for SIGNATURE_DISK_IN_USE");
 
+static struct kmem_cache *prq_cache;
 static struct kmem_cache *pio_cache;
 struct kmem_cache *cow_cache;
 
@@ -175,6 +176,7 @@ static void ploop_destroy(struct ploop *ploop)
 	kfree(ploop->inflight_pios);
 	kfree(ploop->exclusive_pios);
 	mempool_destroy(ploop->pio_pool);
+	mempool_destroy(ploop->prq_pool);
 	kfree(ploop->deltas);
 	kvfree(ploop->holes_bitmap);
 	kvfree(ploop->tracking_bitmap);
@@ -316,6 +318,8 @@ static int ploop_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	if (!ploop)
 		return -ENOMEM;
 
+	ploop->prq_pool = mempool_create_slab_pool(PLOOP_PRQ_POOL_SIZE,
+						   prq_cache);
 	ploop->pio_pool = mempool_create_slab_pool(PLOOP_PIO_POOL_SIZE,
 						   pio_cache);
 	ploop->exclusive_pios = kcalloc(PLOOP_HASH_TABLE_SIZE,
@@ -324,8 +328,8 @@ static int ploop_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	ploop->inflight_pios = kcalloc(PLOOP_HASH_TABLE_SIZE,
 					sizeof(struct hlist_head),
 					GFP_KERNEL);
-	if (!ploop->pio_pool || !ploop->exclusive_pios ||
-				!ploop->inflight_pios) {
+	if (!ploop->prq_pool || !ploop->pio_pool ||
+	    !ploop->exclusive_pios || !ploop->inflight_pios) {
 		ret = -ENOMEM;
 		goto err;
 	}
@@ -531,11 +535,13 @@ static int __init dm_ploop_init(void)
 	int r = -ENOMEM;
 
 	/* This saves some memory in comparison with kmalloc memcache */
+	prq_cache = kmem_cache_create("ploop-prq", sizeof(struct ploop_rq) +
+				      sizeof(struct pio), 0, 0, NULL);
 	pio_cache = kmem_cache_create("ploop-pio", sizeof(struct pio),
 				      0, 0, NULL);
 	cow_cache = kmem_cache_create("ploop-cow", sizeof(struct ploop_cow),
 				      0, 0, NULL);
-	if (!pio_cache || !cow_cache)
+	if (!prq_cache || !pio_cache || !cow_cache)
 		goto err;
 
 	r = dm_register_target(&ploop_target);
@@ -546,6 +552,7 @@ static int __init dm_ploop_init(void)
 
 	return 0;
 err:
+	kmem_cache_destroy(prq_cache);
 	kmem_cache_destroy(pio_cache);
 	kmem_cache_destroy(cow_cache);
 	return r;
@@ -554,6 +561,7 @@ static int __init dm_ploop_init(void)
 static void __exit dm_ploop_exit(void)
 {
 	dm_unregister_target(&ploop_target);
+	kmem_cache_destroy(prq_cache);
 	kmem_cache_destroy(pio_cache);
 	kmem_cache_destroy(cow_cache);
 }
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index aa35d620fe56..8de2a28b2dec 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -137,6 +137,8 @@ enum {
 
 struct ploop {
 	struct dm_target *ti;
+#define PLOOP_PRQ_POOL_SIZE 512 /* Twice nr_requests from blk_mq_init_sched() */
+	mempool_t *prq_pool;
 #define PLOOP_PIO_POOL_SIZE 256
 	mempool_t *pio_pool;
 


More information about the Devel mailing list