Commit e72ec1d3 authored by Javier González's avatar Javier González Committed by Jens Axboe

lightnvm: pblk: do not use a mempool for line bitmaps

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: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarJavier González <javier@cnexlabs.com>
Signed-off-by: default avatarMatias Bjørling <m@bjorling.me>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 0d880398
...@@ -1095,25 +1095,21 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line) ...@@ -1095,25 +1095,21 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
struct pblk_line_meta *lm = &pblk->lm; struct pblk_line_meta *lm = &pblk->lm;
int blk_in_line = atomic_read(&line->blk_in_line); 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) if (!line->map_bitmap)
return -ENOMEM; return -ENOMEM;
memset(line->map_bitmap, 0, lm->sec_bitmap_len);
/* invalid_bitmap is special since it is used when line is closed. No /* will be initialized using bb info from map_bitmap */
* need to zeroized; it will be initialized using bb info form line->invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_ATOMIC);
* map_bitmap
*/
line->invalid_bitmap = mempool_alloc(pblk->line_meta_pool, GFP_ATOMIC);
if (!line->invalid_bitmap) { if (!line->invalid_bitmap) {
mempool_free(line->map_bitmap, pblk->line_meta_pool); kfree(line->map_bitmap);
return -ENOMEM; return -ENOMEM;
} }
spin_lock(&line->lock); spin_lock(&line->lock);
if (line->state != PBLK_LINESTATE_FREE) { if (line->state != PBLK_LINESTATE_FREE) {
mempool_free(line->invalid_bitmap, pblk->line_meta_pool); kfree(line->map_bitmap);
mempool_free(line->map_bitmap, pblk->line_meta_pool); kfree(line->invalid_bitmap);
spin_unlock(&line->lock); spin_unlock(&line->lock);
WARN(1, "pblk: corrupted line %d, state %d\n", WARN(1, "pblk: corrupted line %d, state %d\n",
line->id, line->state); line->id, line->state);
...@@ -1165,7 +1161,7 @@ int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line) ...@@ -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) 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->map_bitmap = NULL;
line->smeta = NULL; line->smeta = NULL;
line->emeta = NULL; line->emeta = NULL;
...@@ -1440,10 +1436,8 @@ void pblk_line_replace_data(struct pblk *pblk) ...@@ -1440,10 +1436,8 @@ void pblk_line_replace_data(struct pblk *pblk)
void pblk_line_free(struct pblk *pblk, struct pblk_line *line) void pblk_line_free(struct pblk *pblk, struct pblk_line *line)
{ {
if (line->map_bitmap) kfree(line->map_bitmap);
mempool_free(line->map_bitmap, pblk->line_meta_pool); kfree(line->invalid_bitmap);
if (line->invalid_bitmap)
mempool_free(line->invalid_bitmap, pblk->line_meta_pool);
*line->vsc = cpu_to_le32(EMPTY_ENTRY); *line->vsc = cpu_to_le32(EMPTY_ENTRY);
...@@ -1584,7 +1578,7 @@ void pblk_line_close(struct pblk *pblk, struct pblk_line *line) ...@@ -1584,7 +1578,7 @@ void pblk_line_close(struct pblk *pblk, struct pblk_line *line)
list_add_tail(&line->list, move_list); 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->map_bitmap = NULL;
line->smeta = NULL; line->smeta = NULL;
line->emeta = NULL; line->emeta = NULL;
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "pblk.h" #include "pblk.h"
static struct kmem_cache *pblk_ws_cache, *pblk_rec_cache, *pblk_g_rq_cache, 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); static DECLARE_RWSEM(pblk_lock);
struct bio_set *pblk_bio_set; struct bio_set *pblk_bio_set;
...@@ -181,8 +181,6 @@ static int pblk_set_ppaf(struct pblk *pblk) ...@@ -181,8 +181,6 @@ static int pblk_set_ppaf(struct pblk *pblk)
static int pblk_init_global_caches(struct pblk *pblk) static int pblk_init_global_caches(struct pblk *pblk)
{ {
char cache_name[PBLK_CACHE_NAME_LEN];
down_write(&pblk_lock); down_write(&pblk_lock);
pblk_ws_cache = kmem_cache_create("pblk_blk_ws", pblk_ws_cache = kmem_cache_create("pblk_blk_ws",
sizeof(struct pblk_line_ws), 0, 0, NULL); sizeof(struct pblk_line_ws), 0, 0, NULL);
...@@ -217,19 +215,6 @@ static int pblk_init_global_caches(struct pblk *pblk) ...@@ -217,19 +215,6 @@ static int pblk_init_global_caches(struct pblk *pblk)
up_write(&pblk_lock); up_write(&pblk_lock);
return -ENOMEM; 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); up_write(&pblk_lock);
return 0; return 0;
...@@ -276,16 +261,10 @@ static int pblk_core_init(struct pblk *pblk) ...@@ -276,16 +261,10 @@ static int pblk_core_init(struct pblk *pblk)
if (!pblk->w_rq_pool) if (!pblk->w_rq_pool)
goto free_e_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", pblk->close_wq = alloc_workqueue("pblk-close-wq",
WQ_MEM_RECLAIM | WQ_UNBOUND, PBLK_NR_CLOSE_JOBS); WQ_MEM_RECLAIM | WQ_UNBOUND, PBLK_NR_CLOSE_JOBS);
if (!pblk->close_wq) if (!pblk->close_wq)
goto free_line_meta_pool; goto free_w_rq_pool;
pblk->bb_wq = alloc_workqueue("pblk-bb-wq", pblk->bb_wq = alloc_workqueue("pblk-bb-wq",
WQ_MEM_RECLAIM | WQ_UNBOUND, 0); WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
...@@ -305,8 +284,6 @@ static int pblk_core_init(struct pblk *pblk) ...@@ -305,8 +284,6 @@ static int pblk_core_init(struct pblk *pblk)
destroy_workqueue(pblk->bb_wq); destroy_workqueue(pblk->bb_wq);
free_close_wq: free_close_wq:
destroy_workqueue(pblk->close_wq); destroy_workqueue(pblk->close_wq);
free_line_meta_pool:
mempool_destroy(pblk->line_meta_pool);
free_w_rq_pool: free_w_rq_pool:
mempool_destroy(pblk->w_rq_pool); mempool_destroy(pblk->w_rq_pool);
free_e_rq_pool: free_e_rq_pool:
...@@ -336,13 +313,11 @@ static void pblk_core_free(struct pblk *pblk) ...@@ -336,13 +313,11 @@ static void pblk_core_free(struct pblk *pblk)
mempool_destroy(pblk->r_rq_pool); mempool_destroy(pblk->r_rq_pool);
mempool_destroy(pblk->e_rq_pool); mempool_destroy(pblk->e_rq_pool);
mempool_destroy(pblk->w_rq_pool); mempool_destroy(pblk->w_rq_pool);
mempool_destroy(pblk->line_meta_pool);
kmem_cache_destroy(pblk_ws_cache); kmem_cache_destroy(pblk_ws_cache);
kmem_cache_destroy(pblk_rec_cache); kmem_cache_destroy(pblk_rec_cache);
kmem_cache_destroy(pblk_g_rq_cache); kmem_cache_destroy(pblk_g_rq_cache);
kmem_cache_destroy(pblk_w_rq_cache); kmem_cache_destroy(pblk_w_rq_cache);
kmem_cache_destroy(pblk_line_meta_cache);
} }
static void pblk_luns_free(struct pblk *pblk) static void pblk_luns_free(struct pblk *pblk)
......
...@@ -987,7 +987,7 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk) ...@@ -987,7 +987,7 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
list_move_tail(&line->list, move_list); list_move_tail(&line->list, move_list);
spin_unlock(&l_mg->gc_lock); spin_unlock(&l_mg->gc_lock);
mempool_free(line->map_bitmap, pblk->line_meta_pool); kfree(line->map_bitmap);
line->map_bitmap = NULL; line->map_bitmap = NULL;
line->smeta = NULL; line->smeta = NULL;
line->emeta = NULL; line->emeta = NULL;
......
...@@ -411,8 +411,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line) ...@@ -411,8 +411,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
if (emeta->mem >= lm->emeta_len[0]) { if (emeta->mem >= lm->emeta_len[0]) {
spin_lock(&l_mg->close_lock); spin_lock(&l_mg->close_lock);
list_del(&meta_line->list); 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); spin_unlock(&l_mg->close_lock);
} }
...@@ -456,7 +454,7 @@ static int pblk_sched_meta_io(struct pblk *pblk, struct ppa_addr *prev_list, ...@@ -456,7 +454,7 @@ static int pblk_sched_meta_io(struct pblk *pblk, struct ppa_addr *prev_list,
return 0; return 0;
} }
meta_line = list_first_entry(&l_mg->emeta_list, struct pblk_line, list); 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; goto retry;
spin_unlock(&l_mg->close_lock); spin_unlock(&l_mg->close_lock);
......
...@@ -40,8 +40,6 @@ ...@@ -40,8 +40,6 @@
#define PBLK_MAX_REQ_ADDRS (64) #define PBLK_MAX_REQ_ADDRS (64)
#define PBLK_MAX_REQ_ADDRS_PW (6) #define PBLK_MAX_REQ_ADDRS_PW (6)
#define PBLK_META_POOL_SIZE (128)
#define PBLK_NR_CLOSE_JOBS (4) #define PBLK_NR_CLOSE_JOBS (4)
#define PBLK_CACHE_NAME_LEN (DISK_NAME_LEN + 16) #define PBLK_CACHE_NAME_LEN (DISK_NAME_LEN + 16)
...@@ -627,7 +625,6 @@ struct pblk { ...@@ -627,7 +625,6 @@ struct pblk {
mempool_t *r_rq_pool; mempool_t *r_rq_pool;
mempool_t *w_rq_pool; mempool_t *w_rq_pool;
mempool_t *e_rq_pool; mempool_t *e_rq_pool;
mempool_t *line_meta_pool;
struct workqueue_struct *close_wq; struct workqueue_struct *close_wq;
struct workqueue_struct *bb_wq; struct workqueue_struct *bb_wq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment