diff options
Diffstat (limited to 'drivers/lightnvm/pblk-core.c')
-rw-r--r-- | drivers/lightnvm/pblk-core.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c index 875f3cf615ac..8ae40855d4c9 100644 --- a/drivers/lightnvm/pblk-core.c +++ b/drivers/lightnvm/pblk-core.c | |||
@@ -237,6 +237,33 @@ static void pblk_invalidate_range(struct pblk *pblk, sector_t slba, | |||
237 | spin_unlock(&pblk->trans_lock); | 237 | spin_unlock(&pblk->trans_lock); |
238 | } | 238 | } |
239 | 239 | ||
240 | int pblk_alloc_rqd_meta(struct pblk *pblk, struct nvm_rq *rqd) | ||
241 | { | ||
242 | struct nvm_tgt_dev *dev = pblk->dev; | ||
243 | |||
244 | rqd->meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, | ||
245 | &rqd->dma_meta_list); | ||
246 | if (!rqd->meta_list) | ||
247 | return -ENOMEM; | ||
248 | |||
249 | if (rqd->nr_ppas == 1) | ||
250 | return 0; | ||
251 | |||
252 | rqd->ppa_list = rqd->meta_list + pblk_dma_meta_size; | ||
253 | rqd->dma_ppa_list = rqd->dma_meta_list + pblk_dma_meta_size; | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | void pblk_free_rqd_meta(struct pblk *pblk, struct nvm_rq *rqd) | ||
259 | { | ||
260 | struct nvm_tgt_dev *dev = pblk->dev; | ||
261 | |||
262 | if (rqd->meta_list) | ||
263 | nvm_dev_dma_free(dev->parent, rqd->meta_list, | ||
264 | rqd->dma_meta_list); | ||
265 | } | ||
266 | |||
240 | /* Caller must guarantee that the request is a valid type */ | 267 | /* Caller must guarantee that the request is a valid type */ |
241 | struct nvm_rq *pblk_alloc_rqd(struct pblk *pblk, int type) | 268 | struct nvm_rq *pblk_alloc_rqd(struct pblk *pblk, int type) |
242 | { | 269 | { |
@@ -268,7 +295,6 @@ struct nvm_rq *pblk_alloc_rqd(struct pblk *pblk, int type) | |||
268 | /* Typically used on completion path. Cannot guarantee request consistency */ | 295 | /* Typically used on completion path. Cannot guarantee request consistency */ |
269 | void pblk_free_rqd(struct pblk *pblk, struct nvm_rq *rqd, int type) | 296 | void pblk_free_rqd(struct pblk *pblk, struct nvm_rq *rqd, int type) |
270 | { | 297 | { |
271 | struct nvm_tgt_dev *dev = pblk->dev; | ||
272 | mempool_t *pool; | 298 | mempool_t *pool; |
273 | 299 | ||
274 | switch (type) { | 300 | switch (type) { |
@@ -289,9 +315,7 @@ void pblk_free_rqd(struct pblk *pblk, struct nvm_rq *rqd, int type) | |||
289 | return; | 315 | return; |
290 | } | 316 | } |
291 | 317 | ||
292 | if (rqd->meta_list) | 318 | pblk_free_rqd_meta(pblk, rqd); |
293 | nvm_dev_dma_free(dev->parent, rqd->meta_list, | ||
294 | rqd->dma_meta_list); | ||
295 | mempool_free(rqd, pool); | 319 | mempool_free(rqd, pool); |
296 | } | 320 | } |
297 | 321 | ||
@@ -838,18 +862,14 @@ static int pblk_line_submit_smeta_io(struct pblk *pblk, struct pblk_line *line, | |||
838 | 862 | ||
839 | memset(&rqd, 0, sizeof(struct nvm_rq)); | 863 | memset(&rqd, 0, sizeof(struct nvm_rq)); |
840 | 864 | ||
841 | rqd.meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, | 865 | ret = pblk_alloc_rqd_meta(pblk, &rqd); |
842 | &rqd.dma_meta_list); | 866 | if (ret) |
843 | if (!rqd.meta_list) | 867 | return ret; |
844 | return -ENOMEM; | ||
845 | |||
846 | rqd.ppa_list = rqd.meta_list + pblk_dma_meta_size; | ||
847 | rqd.dma_ppa_list = rqd.dma_meta_list + pblk_dma_meta_size; | ||
848 | 868 | ||
849 | bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL); | 869 | bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL); |
850 | if (IS_ERR(bio)) { | 870 | if (IS_ERR(bio)) { |
851 | ret = PTR_ERR(bio); | 871 | ret = PTR_ERR(bio); |
852 | goto free_ppa_list; | 872 | goto clear_rqd; |
853 | } | 873 | } |
854 | 874 | ||
855 | bio->bi_iter.bi_sector = 0; /* internal bio */ | 875 | bio->bi_iter.bi_sector = 0; /* internal bio */ |
@@ -881,7 +901,7 @@ static int pblk_line_submit_smeta_io(struct pblk *pblk, struct pblk_line *line, | |||
881 | if (ret) { | 901 | if (ret) { |
882 | pblk_err(pblk, "smeta I/O submission failed: %d\n", ret); | 902 | pblk_err(pblk, "smeta I/O submission failed: %d\n", ret); |
883 | bio_put(bio); | 903 | bio_put(bio); |
884 | goto free_ppa_list; | 904 | goto clear_rqd; |
885 | } | 905 | } |
886 | 906 | ||
887 | atomic_dec(&pblk->inflight_io); | 907 | atomic_dec(&pblk->inflight_io); |
@@ -894,9 +914,8 @@ static int pblk_line_submit_smeta_io(struct pblk *pblk, struct pblk_line *line, | |||
894 | pblk_log_read_err(pblk, &rqd); | 914 | pblk_log_read_err(pblk, &rqd); |
895 | } | 915 | } |
896 | 916 | ||
897 | free_ppa_list: | 917 | clear_rqd: |
898 | nvm_dev_dma_free(dev->parent, rqd.meta_list, rqd.dma_meta_list); | 918 | pblk_free_rqd_meta(pblk, &rqd); |
899 | |||
900 | return ret; | 919 | return ret; |
901 | } | 920 | } |
902 | 921 | ||