aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/pblk-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lightnvm/pblk-core.c')
-rw-r--r--drivers/lightnvm/pblk-core.c51
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
240int 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
258void 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 */
241struct nvm_rq *pblk_alloc_rqd(struct pblk *pblk, int type) 268struct 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 */
269void pblk_free_rqd(struct pblk *pblk, struct nvm_rq *rqd, int type) 296void 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
897free_ppa_list: 917clear_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