diff options
author | Hans Holmberg <hans.holmberg@cnexlabs.com> | 2018-10-09 07:11:47 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-10-09 10:25:07 -0400 |
commit | 53d82db693fe1fd1926066583fd24285fb5aae16 (patch) | |
tree | bd4d71e87e1168ceeb11d922617119382f534350 /drivers/lightnvm | |
parent | d68a9344041b6dd304ff382d0c7805869f09944f (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.c | 22 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-init.c | 18 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-recovery.c | 2 | ||||
-rw-r--r-- | drivers/lightnvm/pblk.h | 4 |
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, | |||
1049 | static int pblk_line_alloc_bitmaps(struct pblk *pblk, struct pblk_line *line) | 1049 | static 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 | ||
1244 | void pblk_line_recov_close(struct pblk *pblk, struct pblk_line *line) | 1247 | void 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 | ||
1262 | void pblk_line_free(struct pblk_line *line) | 1267 | void 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 | ||
503 | static void pblk_line_meta_free(struct pblk_line_mgmt *l_mg, | 506 | static 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); | ||
868 | fail_destroy_bitmap_cache: | ||
869 | kmem_cache_destroy(l_mg->bitmap_cache); | ||
852 | fail_free_smeta: | 870 | fail_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; |