lightnvm: pblk: do not use a mempool for line bitmaps
authorJavier González <javier@cnexlabs.com>
Fri, 13 Oct 2017 12:46:09 +0000 (14:46 +0200)
committerJens Axboe <axboe@kernel.dk>
Fri, 13 Oct 2017 14:34:57 +0000 (08:34 -0600)
pblk holds two sector bitmaps: one to keep track of the mapped sectors
while the line is active and another one to keep track of the invalid
sectors. The latter is kept during the whole live of the line, until it
is recycled. Since we cannot guarantee forward progress for the mempool
in this case, get rid of the mempool and simply allocate memory through
kmalloc.

Reported-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/lightnvm/pblk-core.c
drivers/lightnvm/pblk-init.c
drivers/lightnvm/pblk-recovery.c
drivers/lightnvm/pblk-write.c
drivers/lightnvm/pblk.h

index 0c22e5ccdfdd972f778accc67f02804720a79f98..215aadb84c6e0ff5cc36e2acf57d6973aa5963cf 100644 (file)
@@ -1095,25 +1095,21 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
        struct pblk_line_meta *lm = &pblk->lm;
        int blk_in_line = atomic_read(&line->blk_in_line);
 
-       line->map_bitmap = mempool_alloc(pblk->line_meta_pool, GFP_ATOMIC);
+       line->map_bitmap = kzalloc(lm->sec_bitmap_len, GFP_ATOMIC);
        if (!line->map_bitmap)
                return -ENOMEM;
-       memset(line->map_bitmap, 0, lm->sec_bitmap_len);
 
-       /* invalid_bitmap is special since it is used when line is closed. No
-        * need to zeroized; it will be initialized using bb info form
-        * map_bitmap
-        */
-       line->invalid_bitmap = mempool_alloc(pblk->line_meta_pool, GFP_ATOMIC);
+       /* will be initialized using bb info from map_bitmap */
+       line->invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_ATOMIC);
        if (!line->invalid_bitmap) {
-               mempool_free(line->map_bitmap, pblk->line_meta_pool);
+               kfree(line->map_bitmap);
                return -ENOMEM;
        }
 
        spin_lock(&line->lock);
        if (line->state != PBLK_LINESTATE_FREE) {
-               mempool_free(line->invalid_bitmap, pblk->line_meta_pool);
-               mempool_free(line->map_bitmap, pblk->line_meta_pool);
+               kfree(line->map_bitmap);
+               kfree(line->invalid_bitmap);
                spin_unlock(&line->lock);
                WARN(1, "pblk: corrupted line %d, state %d\n",
                                                        line->id, line->state);
@@ -1165,7 +1161,7 @@ int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line)
 
 void pblk_line_recov_close(struct pblk *pblk, struct pblk_line *line)
 {
-       mempool_free(line->map_bitmap, pblk->line_meta_pool);
+       kfree(line->map_bitmap);
        line->map_bitmap = NULL;
        line->smeta = NULL;
        line->emeta = NULL;
@@ -1440,10 +1436,8 @@ retry_setup:
 
 void pblk_line_free(struct pblk *pblk, struct pblk_line *line)
 {
-       if (line->map_bitmap)
-               mempool_free(line->map_bitmap, pblk->line_meta_pool);
-       if (line->invalid_bitmap)
-               mempool_free(line->invalid_bitmap, pblk->line_meta_pool);
+       kfree(line->map_bitmap);
+       kfree(line->invalid_bitmap);
 
        *line->vsc = cpu_to_le32(EMPTY_ENTRY);
 
@@ -1584,7 +1578,7 @@ void pblk_line_close(struct pblk *pblk, struct pblk_line *line)
 
        list_add_tail(&line->list, move_list);
 
-       mempool_free(line->map_bitmap, pblk->line_meta_pool);
+       kfree(line->map_bitmap);
        line->map_bitmap = NULL;
        line->smeta = NULL;
        line->emeta = NULL;
index 2f8d3f9ffbafc9598edfb5067a7382044893551a..4d719782f65b465b0706bbdd6452d3c0cef81bf4 100644 (file)
@@ -21,7 +21,7 @@
 #include "pblk.h"
 
 static struct kmem_cache *pblk_ws_cache, *pblk_rec_cache, *pblk_g_rq_cache,
-                               *pblk_w_rq_cache, *pblk_line_meta_cache;
+                               *pblk_w_rq_cache;
 static DECLARE_RWSEM(pblk_lock);
 struct bio_set *pblk_bio_set;
 
@@ -181,8 +181,6 @@ static int pblk_set_ppaf(struct pblk *pblk)
 
 static int pblk_init_global_caches(struct pblk *pblk)
 {
-       char cache_name[PBLK_CACHE_NAME_LEN];
-
        down_write(&pblk_lock);
        pblk_ws_cache = kmem_cache_create("pblk_blk_ws",
                                sizeof(struct pblk_line_ws), 0, 0, NULL);
@@ -217,19 +215,6 @@ static int pblk_init_global_caches(struct pblk *pblk)
                up_write(&pblk_lock);
                return -ENOMEM;
        }
-
-       snprintf(cache_name, sizeof(cache_name), "pblk_line_m_%s",
-                                                       pblk->disk->disk_name);
-       pblk_line_meta_cache = kmem_cache_create(cache_name,
-                               pblk->lm.sec_bitmap_len, 0, 0, NULL);
-       if (!pblk_line_meta_cache) {
-               kmem_cache_destroy(pblk_ws_cache);
-               kmem_cache_destroy(pblk_rec_cache);
-               kmem_cache_destroy(pblk_g_rq_cache);
-               kmem_cache_destroy(pblk_w_rq_cache);
-               up_write(&pblk_lock);
-               return -ENOMEM;
-       }
        up_write(&pblk_lock);
 
        return 0;
@@ -276,16 +261,10 @@ static int pblk_core_init(struct pblk *pblk)
        if (!pblk->w_rq_pool)
                goto free_e_rq_pool;
 
-       pblk->line_meta_pool =
-                       mempool_create_slab_pool(PBLK_META_POOL_SIZE,
-                                                       pblk_line_meta_cache);
-       if (!pblk->line_meta_pool)
-               goto free_w_rq_pool;
-
        pblk->close_wq = alloc_workqueue("pblk-close-wq",
                        WQ_MEM_RECLAIM | WQ_UNBOUND, PBLK_NR_CLOSE_JOBS);
        if (!pblk->close_wq)
-               goto free_line_meta_pool;
+               goto free_w_rq_pool;
 
        pblk->bb_wq = alloc_workqueue("pblk-bb-wq",
                        WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
@@ -305,8 +284,6 @@ free_bb_wq:
        destroy_workqueue(pblk->bb_wq);
 free_close_wq:
        destroy_workqueue(pblk->close_wq);
-free_line_meta_pool:
-       mempool_destroy(pblk->line_meta_pool);
 free_w_rq_pool:
        mempool_destroy(pblk->w_rq_pool);
 free_e_rq_pool:
@@ -336,13 +313,11 @@ static void pblk_core_free(struct pblk *pblk)
        mempool_destroy(pblk->r_rq_pool);
        mempool_destroy(pblk->e_rq_pool);
        mempool_destroy(pblk->w_rq_pool);
-       mempool_destroy(pblk->line_meta_pool);
 
        kmem_cache_destroy(pblk_ws_cache);
        kmem_cache_destroy(pblk_rec_cache);
        kmem_cache_destroy(pblk_g_rq_cache);
        kmem_cache_destroy(pblk_w_rq_cache);
-       kmem_cache_destroy(pblk_line_meta_cache);
 }
 
 static void pblk_luns_free(struct pblk *pblk)
index caf1242795757b202a25b824aa824d25baa5a333..de5270712be77137c98a1e37459d5afe5bafcf32 100644 (file)
@@ -987,7 +987,7 @@ next:
                        list_move_tail(&line->list, move_list);
                        spin_unlock(&l_mg->gc_lock);
 
-                       mempool_free(line->map_bitmap, pblk->line_meta_pool);
+                       kfree(line->map_bitmap);
                        line->map_bitmap = NULL;
                        line->smeta = NULL;
                        line->emeta = NULL;
index c73b17bca06b0cb7abf03a0534223d6ec9b91892..26c2b83451497346952fbf5dd18451f695f88419 100644 (file)
@@ -411,8 +411,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
        if (emeta->mem >= lm->emeta_len[0]) {
                spin_lock(&l_mg->close_lock);
                list_del(&meta_line->list);
-               WARN(!bitmap_full(meta_line->map_bitmap, lm->sec_per_line),
-                               "pblk: corrupt meta line %d\n", meta_line->id);
                spin_unlock(&l_mg->close_lock);
        }
 
@@ -456,7 +454,7 @@ retry:
                return 0;
        }
        meta_line = list_first_entry(&l_mg->emeta_list, struct pblk_line, list);
-       if (bitmap_full(meta_line->map_bitmap, lm->sec_per_line))
+       if (meta_line->emeta->mem >= lm->emeta_len[0])
                goto retry;
        spin_unlock(&l_mg->close_lock);
 
index 419e1b7328e4087bdbad99708aa46e6fa13f79b2..60edcda0fc7f7428f8a0bd055382c716805cb2d3 100644 (file)
@@ -40,8 +40,6 @@
 #define PBLK_MAX_REQ_ADDRS (64)
 #define PBLK_MAX_REQ_ADDRS_PW (6)
 
-#define PBLK_META_POOL_SIZE (128)
-
 #define PBLK_NR_CLOSE_JOBS (4)
 
 #define PBLK_CACHE_NAME_LEN (DISK_NAME_LEN + 16)
@@ -627,7 +625,6 @@ struct pblk {
        mempool_t *r_rq_pool;
        mempool_t *w_rq_pool;
        mempool_t *e_rq_pool;
-       mempool_t *line_meta_pool;
 
        struct workqueue_struct *close_wq;
        struct workqueue_struct *bb_wq;