aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm
diff options
context:
space:
mode:
authorHans Holmberg <hans.holmberg@cnexlabs.com>2018-10-09 07:11:47 -0400
committerJens Axboe <axboe@kernel.dk>2018-10-09 10:25:07 -0400
commit53d82db693fe1fd1926066583fd24285fb5aae16 (patch)
treebd4d71e87e1168ceeb11d922617119382f534350 /drivers/lightnvm
parentd68a9344041b6dd304ff382d0c7805869f09944f (diff)
lightnvm: pblk: allocate line map bitmaps using a mempool
Line map bitmap allocations are fairly large and can fail. Allocation failures are fatal to pblk, stopping the write pipeline. To avoid this, allocate the bitmaps using a mempool instead. Mempool allocations never fail if called from a process context, and pblk *should* only allocate map bitmaps in process context, but keep the failure handling for robustness sake. Signed-off-by: Hans Holmberg <hans.holmberg@cnexlabs.com> Signed-off-by: Matias Bjørling <mb@lightnvm.io> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/lightnvm')
-rw-r--r--drivers/lightnvm/pblk-core.c22
-rw-r--r--drivers/lightnvm/pblk-init.c18
-rw-r--r--drivers/lightnvm/pblk-recovery.c2
-rw-r--r--drivers/lightnvm/pblk.h4
4 files changed, 38 insertions, 8 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index a31417682c90..e1207a4f9d54 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1049,15 +1049,18 @@ static int pblk_line_init_metadata(struct pblk *pblk, struct pblk_line *line,
1049static int pblk_line_alloc_bitmaps(struct pblk *pblk, struct pblk_line *line) 1049static int pblk_line_alloc_bitmaps(struct pblk *pblk, struct pblk_line *line)
1050{ 1050{
1051 struct pblk_line_meta *lm = &pblk->lm; 1051 struct pblk_line_meta *lm = &pblk->lm;
1052 struct pblk_line_mgmt *l_mg = &pblk->l_mg;
1052 1053
1053 line->map_bitmap = kzalloc(lm->sec_bitmap_len, GFP_KERNEL); 1054 line->map_bitmap = mempool_alloc(l_mg->bitmap_pool, GFP_KERNEL);
1054 if (!line->map_bitmap) 1055 if (!line->map_bitmap)
1055 return -ENOMEM; 1056 return -ENOMEM;
1056 1057
1058 memset(line->map_bitmap, 0, lm->sec_bitmap_len);
1059
1057 /* will be initialized using bb info from map_bitmap */ 1060 /* will be initialized using bb info from map_bitmap */
1058 line->invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_KERNEL); 1061 line->invalid_bitmap = mempool_alloc(l_mg->bitmap_pool, GFP_KERNEL);
1059 if (!line->invalid_bitmap) { 1062 if (!line->invalid_bitmap) {
1060 kfree(line->map_bitmap); 1063 mempool_free(line->map_bitmap, l_mg->bitmap_pool);
1061 line->map_bitmap = NULL; 1064 line->map_bitmap = NULL;
1062 return -ENOMEM; 1065 return -ENOMEM;
1063 } 1066 }
@@ -1243,7 +1246,9 @@ int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line)
1243 1246
1244void pblk_line_recov_close(struct pblk *pblk, struct pblk_line *line) 1247void pblk_line_recov_close(struct pblk *pblk, struct pblk_line *line)
1245{ 1248{
1246 kfree(line->map_bitmap); 1249 struct pblk_line_mgmt *l_mg = &pblk->l_mg;
1250
1251 mempool_free(line->map_bitmap, l_mg->bitmap_pool);
1247 line->map_bitmap = NULL; 1252 line->map_bitmap = NULL;
1248 line->smeta = NULL; 1253 line->smeta = NULL;
1249 line->emeta = NULL; 1254 line->emeta = NULL;
@@ -1261,8 +1266,11 @@ static void pblk_line_reinit(struct pblk_line *line)
1261 1266
1262void pblk_line_free(struct pblk_line *line) 1267void pblk_line_free(struct pblk_line *line)
1263{ 1268{
1264 kfree(line->map_bitmap); 1269 struct pblk *pblk = line->pblk;
1265 kfree(line->invalid_bitmap); 1270 struct pblk_line_mgmt *l_mg = &pblk->l_mg;
1271
1272 mempool_free(line->map_bitmap, l_mg->bitmap_pool);
1273 mempool_free(line->invalid_bitmap, l_mg->bitmap_pool);
1266 1274
1267 pblk_line_reinit(line); 1275 pblk_line_reinit(line);
1268} 1276}
@@ -1741,7 +1749,7 @@ void pblk_line_close(struct pblk *pblk, struct pblk_line *line)
1741 1749
1742 list_add_tail(&line->list, move_list); 1750 list_add_tail(&line->list, move_list);
1743 1751
1744 kfree(line->map_bitmap); 1752 mempool_free(line->map_bitmap, l_mg->bitmap_pool);
1745 line->map_bitmap = NULL; 1753 line->map_bitmap = NULL;
1746 line->smeta = NULL; 1754 line->smeta = NULL;
1747 line->emeta = NULL; 1755 line->emeta = NULL;
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 8adc8ac8b03c..76a4a271b9cf 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -498,6 +498,9 @@ static void pblk_line_mg_free(struct pblk *pblk)
498 pblk_mfree(l_mg->eline_meta[i]->buf, l_mg->emeta_alloc_type); 498 pblk_mfree(l_mg->eline_meta[i]->buf, l_mg->emeta_alloc_type);
499 kfree(l_mg->eline_meta[i]); 499 kfree(l_mg->eline_meta[i]);
500 } 500 }
501
502 mempool_destroy(l_mg->bitmap_pool);
503 kmem_cache_destroy(l_mg->bitmap_cache);
501} 504}
502 505
503static void pblk_line_meta_free(struct pblk_line_mgmt *l_mg, 506static void pblk_line_meta_free(struct pblk_line_mgmt *l_mg,
@@ -797,6 +800,17 @@ static int pblk_line_mg_init(struct pblk *pblk)
797 goto fail_free_smeta; 800 goto fail_free_smeta;
798 } 801 }
799 802
803 l_mg->bitmap_cache = kmem_cache_create("pblk_lm_bitmap",
804 lm->sec_bitmap_len, 0, 0, NULL);
805 if (!l_mg->bitmap_cache)
806 goto fail_free_smeta;
807
808 /* the bitmap pool is used for both valid and map bitmaps */
809 l_mg->bitmap_pool = mempool_create_slab_pool(PBLK_DATA_LINES * 2,
810 l_mg->bitmap_cache);
811 if (!l_mg->bitmap_pool)
812 goto fail_destroy_bitmap_cache;
813
800 /* emeta allocates three different buffers for managing metadata with 814 /* emeta allocates three different buffers for managing metadata with
801 * in-memory and in-media layouts 815 * in-memory and in-media layouts
802 */ 816 */
@@ -849,6 +863,10 @@ fail_free_emeta:
849 kfree(l_mg->eline_meta[i]->buf); 863 kfree(l_mg->eline_meta[i]->buf);
850 kfree(l_mg->eline_meta[i]); 864 kfree(l_mg->eline_meta[i]);
851 } 865 }
866
867 mempool_destroy(l_mg->bitmap_pool);
868fail_destroy_bitmap_cache:
869 kmem_cache_destroy(l_mg->bitmap_cache);
852fail_free_smeta: 870fail_free_smeta:
853 for (i = 0; i < PBLK_DATA_LINES; i++) 871 for (i = 0; i < PBLK_DATA_LINES; i++)
854 kfree(l_mg->sline_meta[i]); 872 kfree(l_mg->sline_meta[i]);
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
index 3bd2b6b0a359..eea901d7cebc 100644
--- a/drivers/lightnvm/pblk-recovery.c
+++ b/drivers/lightnvm/pblk-recovery.c
@@ -939,7 +939,7 @@ next:
939 list_move_tail(&line->list, move_list); 939 list_move_tail(&line->list, move_list);
940 spin_unlock(&l_mg->gc_lock); 940 spin_unlock(&l_mg->gc_lock);
941 941
942 kfree(line->map_bitmap); 942 mempool_free(line->map_bitmap, l_mg->bitmap_pool);
943 line->map_bitmap = NULL; 943 line->map_bitmap = NULL;
944 line->smeta = NULL; 944 line->smeta = NULL;
945 line->emeta = NULL; 945 line->emeta = NULL;
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 60c509a00574..9068b158de22 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -530,6 +530,10 @@ struct pblk_line_mgmt {
530 struct pblk_emeta *eline_meta[PBLK_DATA_LINES]; 530 struct pblk_emeta *eline_meta[PBLK_DATA_LINES];
531 unsigned long meta_bitmap; 531 unsigned long meta_bitmap;
532 532
533 /* Cache and mempool for map/invalid bitmaps */
534 struct kmem_cache *bitmap_cache;
535 mempool_t *bitmap_pool;
536
533 /* Helpers for fast bitmap calculations */ 537 /* Helpers for fast bitmap calculations */
534 unsigned long *bb_template; 538 unsigned long *bb_template;
535 unsigned long *bb_aux; 539 unsigned long *bb_aux;