[Devel] [PATCH RH8 2/2] dm-ploop: Introduce memcache for prq

Kirill Tkhai ktkhai at virtuozzo.com
Thu Aug 19 20:37:55 MSK 2021


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