linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] lnvm/pblk mapping cleanups
@ 2019-07-31  9:41 Hans Holmberg
  2019-07-31  9:41 ` [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn Hans Holmberg
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: Hans Holmberg @ 2019-07-31  9:41 UTC (permalink / raw)
  To: Matias Bjorling
  Cc: Christoph Hellwig, Javier González, linux-block,
	linux-kernel, Hans Holmberg

This series cleans up the metadata allocation/mapping in lnvm/pblk
by moving over to kvmalloc for metadata and moving metadata mapping
down to the lower lever driver where blk_rq_map_kern can be used.

Hans Holmberg (4):
  lightnvm: remove nvm_submit_io_sync_fn
  lightnvm: move metadata mapping to lower level driver
  lightnvm: pblk: use kvmalloc for metadata
  block: stop exporting bio_map_kern

 block/bio.c                      |   1 -
 drivers/lightnvm/core.c          |  43 ++++++++++++---
 drivers/lightnvm/pblk-core.c     | 116 +++++----------------------------------
 drivers/lightnvm/pblk-gc.c       |  19 +++----
 drivers/lightnvm/pblk-init.c     |  38 ++++---------
 drivers/lightnvm/pblk-read.c     |  22 +-------
 drivers/lightnvm/pblk-recovery.c |  39 ++-----------
 drivers/lightnvm/pblk-write.c    |  20 +------
 drivers/lightnvm/pblk.h          |  31 +----------
 drivers/nvme/host/lightnvm.c     |  45 +++++----------
 include/linux/lightnvm.h         |   8 +--
 11 files changed, 96 insertions(+), 286 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn
  2019-07-31  9:41 [PATCH 0/4] lnvm/pblk mapping cleanups Hans Holmberg
@ 2019-07-31  9:41 ` Hans Holmberg
  2019-07-31 13:54   ` Javier González
  2019-08-06  7:05   ` Christoph Hellwig
  2019-07-31  9:41 ` [PATCH 2/4] lightnvm: move metadata mapping to lower level driver Hans Holmberg
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 17+ messages in thread
From: Hans Holmberg @ 2019-07-31  9:41 UTC (permalink / raw)
  To: Matias Bjorling
  Cc: Christoph Hellwig, Javier González, linux-block,
	linux-kernel, Hans Holmberg

Move the redundant sync handling interface and wait for a completion
in the lightnvm core instead.

Signed-off-by: Hans Holmberg <hans@owltronix.com>
---
 drivers/lightnvm/core.c      | 35 +++++++++++++++++++++++++++++------
 drivers/nvme/host/lightnvm.c | 29 -----------------------------
 include/linux/lightnvm.h     |  2 --
 3 files changed, 29 insertions(+), 37 deletions(-)

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index a600934fdd9c..01d098fb96ac 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -752,12 +752,36 @@ int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
 }
 EXPORT_SYMBOL(nvm_submit_io);
 
+static void nvm_sync_end_io(struct nvm_rq *rqd)
+{
+	struct completion *waiting = rqd->private;
+
+	complete(waiting);
+}
+
+static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+	int ret = 0;
+
+	rqd->end_io = nvm_sync_end_io;
+	rqd->private = &wait;
+
+	ret = dev->ops->submit_io(dev, rqd);
+	if (ret)
+		return ret;
+
+	wait_for_completion_io(&wait);
+
+	return 0;
+}
+
 int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
 {
 	struct nvm_dev *dev = tgt_dev->parent;
 	int ret;
 
-	if (!dev->ops->submit_io_sync)
+	if (!dev->ops->submit_io)
 		return -ENODEV;
 
 	nvm_rq_tgt_to_dev(tgt_dev, rqd);
@@ -765,9 +789,7 @@ int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
 	rqd->dev = tgt_dev;
 	rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
 
-	/* In case of error, fail with right address format */
-	ret = dev->ops->submit_io_sync(dev, rqd);
-	nvm_rq_dev_to_tgt(tgt_dev, rqd);
+	ret = nvm_submit_io_wait(dev, rqd);
 
 	return ret;
 }
@@ -788,12 +810,13 @@ EXPORT_SYMBOL(nvm_end_io);
 
 static int nvm_submit_io_sync_raw(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
-	if (!dev->ops->submit_io_sync)
+	if (!dev->ops->submit_io)
 		return -ENODEV;
 
+	rqd->dev = NULL;
 	rqd->flags = nvm_set_flags(&dev->geo, rqd);
 
-	return dev->ops->submit_io_sync(dev, rqd);
+	return nvm_submit_io_wait(dev, rqd);
 }
 
 static int nvm_bb_chunk_sense(struct nvm_dev *dev, struct ppa_addr ppa)
diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index ba009d4c9dfa..d6f121452d5d 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -690,34 +690,6 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 	return 0;
 }
 
-static int nvme_nvm_submit_io_sync(struct nvm_dev *dev, struct nvm_rq *rqd)
-{
-	struct request_queue *q = dev->q;
-	struct request *rq;
-	struct nvme_nvm_command cmd;
-	int ret = 0;
-
-	memset(&cmd, 0, sizeof(struct nvme_nvm_command));
-
-	rq = nvme_nvm_alloc_request(q, rqd, &cmd);
-	if (IS_ERR(rq))
-		return PTR_ERR(rq);
-
-	/* I/Os can fail and the error is signaled through rqd. Callers must
-	 * handle the error accordingly.
-	 */
-	blk_execute_rq(q, NULL, rq, 0);
-	if (nvme_req(rq)->flags & NVME_REQ_CANCELLED)
-		ret = -EINTR;
-
-	rqd->ppa_status = le64_to_cpu(nvme_req(rq)->result.u64);
-	rqd->error = nvme_req(rq)->status;
-
-	blk_mq_free_request(rq);
-
-	return ret;
-}
-
 static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name,
 					int size)
 {
@@ -754,7 +726,6 @@ static struct nvm_dev_ops nvme_nvm_dev_ops = {
 	.get_chk_meta		= nvme_nvm_get_chk_meta,
 
 	.submit_io		= nvme_nvm_submit_io,
-	.submit_io_sync		= nvme_nvm_submit_io_sync,
 
 	.create_dma_pool	= nvme_nvm_create_dma_pool,
 	.destroy_dma_pool	= nvme_nvm_destroy_dma_pool,
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index 4d0d5655c7b2..8891647b24b1 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -89,7 +89,6 @@ typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
 typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, sector_t, int,
 							struct nvm_chk_meta *);
 typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef int (nvm_submit_io_sync_fn)(struct nvm_dev *, struct nvm_rq *);
 typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *, int);
 typedef void (nvm_destroy_dma_pool_fn)(void *);
 typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
@@ -104,7 +103,6 @@ struct nvm_dev_ops {
 	nvm_get_chk_meta_fn	*get_chk_meta;
 
 	nvm_submit_io_fn	*submit_io;
-	nvm_submit_io_sync_fn	*submit_io_sync;
 
 	nvm_create_dma_pool_fn	*create_dma_pool;
 	nvm_destroy_dma_pool_fn	*destroy_dma_pool;
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 2/4] lightnvm: move metadata mapping to lower level driver
  2019-07-31  9:41 [PATCH 0/4] lnvm/pblk mapping cleanups Hans Holmberg
  2019-07-31  9:41 ` [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn Hans Holmberg
@ 2019-07-31  9:41 ` Hans Holmberg
  2019-07-31 13:58   ` Javier González
  2019-08-06  7:06   ` Christoph Hellwig
  2019-07-31  9:41 ` [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata Hans Holmberg
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 17+ messages in thread
From: Hans Holmberg @ 2019-07-31  9:41 UTC (permalink / raw)
  To: Matias Bjorling
  Cc: Christoph Hellwig, Javier González, linux-block,
	linux-kernel, Hans Holmberg

Now that blk_rq_map_kern can map both kmem and vmem, move
internal metadata mapping down to the lower level driver.

Signed-off-by: Hans Holmberg <hans@owltronix.com>
---
 drivers/lightnvm/core.c          |  16 +++---
 drivers/lightnvm/pblk-core.c     | 113 +++++----------------------------------
 drivers/lightnvm/pblk-read.c     |  22 ++------
 drivers/lightnvm/pblk-recovery.c |  39 ++------------
 drivers/lightnvm/pblk-write.c    |  20 ++-----
 drivers/lightnvm/pblk.h          |   8 +--
 drivers/nvme/host/lightnvm.c     |  20 +++++--
 include/linux/lightnvm.h         |   6 +--
 8 files changed, 54 insertions(+), 190 deletions(-)

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 01d098fb96ac..3cd03582a2ed 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -731,7 +731,7 @@ static int nvm_set_flags(struct nvm_geo *geo, struct nvm_rq *rqd)
 	return flags;
 }
 
-int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
+int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd, void *buf)
 {
 	struct nvm_dev *dev = tgt_dev->parent;
 	int ret;
@@ -745,7 +745,7 @@ int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
 	rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
 
 	/* In case of error, fail with right address format */
-	ret = dev->ops->submit_io(dev, rqd);
+	ret = dev->ops->submit_io(dev, rqd, buf);
 	if (ret)
 		nvm_rq_dev_to_tgt(tgt_dev, rqd);
 	return ret;
@@ -759,7 +759,8 @@ static void nvm_sync_end_io(struct nvm_rq *rqd)
 	complete(waiting);
 }
 
-static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
+static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd,
+			      void *buf)
 {
 	DECLARE_COMPLETION_ONSTACK(wait);
 	int ret = 0;
@@ -767,7 +768,7 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
 	rqd->end_io = nvm_sync_end_io;
 	rqd->private = &wait;
 
-	ret = dev->ops->submit_io(dev, rqd);
+	ret = dev->ops->submit_io(dev, rqd, buf);
 	if (ret)
 		return ret;
 
@@ -776,7 +777,8 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
 	return 0;
 }
 
-int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
+int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd,
+		       void *buf)
 {
 	struct nvm_dev *dev = tgt_dev->parent;
 	int ret;
@@ -789,7 +791,7 @@ int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
 	rqd->dev = tgt_dev;
 	rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
 
-	ret = nvm_submit_io_wait(dev, rqd);
+	ret = nvm_submit_io_wait(dev, rqd, buf);
 
 	return ret;
 }
@@ -816,7 +818,7 @@ static int nvm_submit_io_sync_raw(struct nvm_dev *dev, struct nvm_rq *rqd)
 	rqd->dev = NULL;
 	rqd->flags = nvm_set_flags(&dev->geo, rqd);
 
-	return nvm_submit_io_wait(dev, rqd);
+	return nvm_submit_io_wait(dev, rqd, NULL);
 }
 
 static int nvm_bb_chunk_sense(struct nvm_dev *dev, struct ppa_addr ppa)
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index f546e6f28b8a..a58d3c84a3f2 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -507,7 +507,7 @@ void pblk_set_sec_per_write(struct pblk *pblk, int sec_per_write)
 	pblk->sec_per_write = sec_per_write;
 }
 
-int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
+int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 
@@ -518,7 +518,7 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
 		return NVM_IO_ERR;
 #endif
 
-	return nvm_submit_io(dev, rqd);
+	return nvm_submit_io(dev, rqd, buf);
 }
 
 void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
@@ -541,7 +541,7 @@ void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
 	}
 }
 
-int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
+int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	int ret;
@@ -553,7 +553,7 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
 		return NVM_IO_ERR;
 #endif
 
-	ret = nvm_submit_io_sync(dev, rqd);
+	ret = nvm_submit_io_sync(dev, rqd, buf);
 
 	if (trace_pblk_chunk_state_enabled() && !ret &&
 	    rqd->opcode == NVM_OP_PWRITE)
@@ -562,65 +562,19 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
 	return ret;
 }
 
-int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd)
+static int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd,
+				   void *buf)
 {
 	struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
 	int ret;
 
 	pblk_down_chunk(pblk, ppa_list[0]);
-	ret = pblk_submit_io_sync(pblk, rqd);
+	ret = pblk_submit_io_sync(pblk, rqd, buf);
 	pblk_up_chunk(pblk, ppa_list[0]);
 
 	return ret;
 }
 
-static void pblk_bio_map_addr_endio(struct bio *bio)
-{
-	bio_put(bio);
-}
-
-struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
-			      unsigned int nr_secs, unsigned int len,
-			      int alloc_type, gfp_t gfp_mask)
-{
-	struct nvm_tgt_dev *dev = pblk->dev;
-	void *kaddr = data;
-	struct page *page;
-	struct bio *bio;
-	int i, ret;
-
-	if (alloc_type == PBLK_KMALLOC_META)
-		return bio_map_kern(dev->q, kaddr, len, gfp_mask);
-
-	bio = bio_kmalloc(gfp_mask, nr_secs);
-	if (!bio)
-		return ERR_PTR(-ENOMEM);
-
-	for (i = 0; i < nr_secs; i++) {
-		page = vmalloc_to_page(kaddr);
-		if (!page) {
-			pblk_err(pblk, "could not map vmalloc bio\n");
-			bio_put(bio);
-			bio = ERR_PTR(-ENOMEM);
-			goto out;
-		}
-
-		ret = bio_add_pc_page(dev->q, bio, page, PAGE_SIZE, 0);
-		if (ret != PAGE_SIZE) {
-			pblk_err(pblk, "could not add page to bio\n");
-			bio_put(bio);
-			bio = ERR_PTR(-ENOMEM);
-			goto out;
-		}
-
-		kaddr += PAGE_SIZE;
-	}
-
-	bio->bi_end_io = pblk_bio_map_addr_endio;
-out:
-	return bio;
-}
-
 int pblk_calc_secs(struct pblk *pblk, unsigned long secs_avail,
 		   unsigned long secs_to_flush, bool skip_meta)
 {
@@ -722,9 +676,7 @@ u64 pblk_line_smeta_start(struct pblk *pblk, struct pblk_line *line)
 
 int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
 {
-	struct nvm_tgt_dev *dev = pblk->dev;
 	struct pblk_line_meta *lm = &pblk->lm;
-	struct bio *bio;
 	struct ppa_addr *ppa_list;
 	struct nvm_rq rqd;
 	u64 paddr = pblk_line_smeta_start(pblk, line);
@@ -736,16 +688,6 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
 	if (ret)
 		return ret;
 
-	bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
-	if (IS_ERR(bio)) {
-		ret = PTR_ERR(bio);
-		goto clear_rqd;
-	}
-
-	bio->bi_iter.bi_sector = 0; /* internal bio */
-	bio_set_op_attrs(bio, REQ_OP_READ, 0);
-
-	rqd.bio = bio;
 	rqd.opcode = NVM_OP_PREAD;
 	rqd.nr_ppas = lm->smeta_sec;
 	rqd.is_seq = 1;
@@ -754,10 +696,9 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
 	for (i = 0; i < lm->smeta_sec; i++, paddr++)
 		ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line->id);
 
-	ret = pblk_submit_io_sync(pblk, &rqd);
+	ret = pblk_submit_io_sync(pblk, &rqd, line->smeta);
 	if (ret) {
 		pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
-		bio_put(bio);
 		goto clear_rqd;
 	}
 
@@ -776,9 +717,7 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
 static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
 				 u64 paddr)
 {
-	struct nvm_tgt_dev *dev = pblk->dev;
 	struct pblk_line_meta *lm = &pblk->lm;
-	struct bio *bio;
 	struct ppa_addr *ppa_list;
 	struct nvm_rq rqd;
 	__le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
@@ -791,16 +730,6 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
 	if (ret)
 		return ret;
 
-	bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
-	if (IS_ERR(bio)) {
-		ret = PTR_ERR(bio);
-		goto clear_rqd;
-	}
-
-	bio->bi_iter.bi_sector = 0; /* internal bio */
-	bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
-
-	rqd.bio = bio;
 	rqd.opcode = NVM_OP_PWRITE;
 	rqd.nr_ppas = lm->smeta_sec;
 	rqd.is_seq = 1;
@@ -814,10 +743,9 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
 		meta->lba = lba_list[paddr] = addr_empty;
 	}
 
-	ret = pblk_submit_io_sync_sem(pblk, &rqd);
+	ret = pblk_submit_io_sync_sem(pblk, &rqd, line->smeta);
 	if (ret) {
 		pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
-		bio_put(bio);
 		goto clear_rqd;
 	}
 
@@ -838,10 +766,8 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
-	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	struct pblk_line_meta *lm = &pblk->lm;
 	void *ppa_list_buf, *meta_list;
-	struct bio *bio;
 	struct ppa_addr *ppa_list;
 	struct nvm_rq rqd;
 	u64 paddr = line->emeta_ssec;
@@ -867,17 +793,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
 	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
 	rq_len = rq_ppas * geo->csecs;
 
-	bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len,
-					l_mg->emeta_alloc_type, GFP_KERNEL);
-	if (IS_ERR(bio)) {
-		ret = PTR_ERR(bio);
-		goto free_rqd_dma;
-	}
-
-	bio->bi_iter.bi_sector = 0; /* internal bio */
-	bio_set_op_attrs(bio, REQ_OP_READ, 0);
-
-	rqd.bio = bio;
 	rqd.meta_list = meta_list;
 	rqd.ppa_list = ppa_list_buf;
 	rqd.dma_meta_list = dma_meta_list;
@@ -896,7 +811,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
 		while (test_bit(pos, line->blk_bitmap)) {
 			paddr += min;
 			if (pblk_boundary_paddr_checks(pblk, paddr)) {
-				bio_put(bio);
 				ret = -EINTR;
 				goto free_rqd_dma;
 			}
@@ -906,7 +820,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
 		}
 
 		if (pblk_boundary_paddr_checks(pblk, paddr + min)) {
-			bio_put(bio);
 			ret = -EINTR;
 			goto free_rqd_dma;
 		}
@@ -915,10 +828,9 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
 			ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line_id);
 	}
 
-	ret = pblk_submit_io_sync(pblk, &rqd);
+	ret = pblk_submit_io_sync(pblk, &rqd, emeta_buf);
 	if (ret) {
 		pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
-		bio_put(bio);
 		goto free_rqd_dma;
 	}
 
@@ -963,7 +875,7 @@ static int pblk_blk_erase_sync(struct pblk *pblk, struct ppa_addr ppa)
 	/* The write thread schedules erases so that it minimizes disturbances
 	 * with writes. Thus, there is no need to take the LUN semaphore.
 	 */
-	ret = pblk_submit_io_sync(pblk, &rqd);
+	ret = pblk_submit_io_sync(pblk, &rqd, NULL);
 	rqd.private = pblk;
 	__pblk_end_io_erase(pblk, &rqd);
 
@@ -1792,7 +1704,7 @@ int pblk_blk_erase_async(struct pblk *pblk, struct ppa_addr ppa)
 	/* The write thread schedules erases so that it minimizes disturbances
 	 * with writes. Thus, there is no need to take the LUN semaphore.
 	 */
-	err = pblk_submit_io(pblk, rqd);
+	err = pblk_submit_io(pblk, rqd, NULL);
 	if (err) {
 		struct nvm_tgt_dev *dev = pblk->dev;
 		struct nvm_geo *geo = &dev->geo;
@@ -1923,7 +1835,6 @@ void pblk_line_close_meta(struct pblk *pblk, struct pblk_line *line)
 static void pblk_save_lba_list(struct pblk *pblk, struct pblk_line *line)
 {
 	struct pblk_line_meta *lm = &pblk->lm;
-	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	unsigned int lba_list_size = lm->emeta_len[2];
 	struct pblk_w_err_gc *w_err_gc = line->w_err_gc;
 	struct pblk_emeta *emeta = line->emeta;
diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c
index d98ea392fe33..d572d4559e4e 100644
--- a/drivers/lightnvm/pblk-read.c
+++ b/drivers/lightnvm/pblk-read.c
@@ -342,7 +342,7 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio)
 		bio_put(int_bio);
 		int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set);
 		goto split_retry;
-	} else if (pblk_submit_io(pblk, rqd)) {
+	} else if (pblk_submit_io(pblk, rqd, NULL)) {
 		/* Submitting IO to drive failed, let's report an error */
 		rqd->error = -ENODEV;
 		pblk_end_io_read(rqd);
@@ -419,7 +419,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
-	struct bio *bio;
 	struct nvm_rq rqd;
 	int data_len;
 	int ret = NVM_IO_OK;
@@ -447,25 +446,12 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
 		goto out;
 
 	data_len = (gc_rq->secs_to_gc) * geo->csecs;
-	bio = pblk_bio_map_addr(pblk, gc_rq->data, gc_rq->secs_to_gc, data_len,
-						PBLK_VMALLOC_META, GFP_KERNEL);
-	if (IS_ERR(bio)) {
-		pblk_err(pblk, "could not allocate GC bio (%lu)\n",
-								PTR_ERR(bio));
-		ret = PTR_ERR(bio);
-		goto err_free_dma;
-	}
-
-	bio->bi_iter.bi_sector = 0; /* internal bio */
-	bio_set_op_attrs(bio, REQ_OP_READ, 0);
-
 	rqd.opcode = NVM_OP_PREAD;
 	rqd.nr_ppas = gc_rq->secs_to_gc;
-	rqd.bio = bio;
 
-	if (pblk_submit_io_sync(pblk, &rqd)) {
+	if (pblk_submit_io_sync(pblk, &rqd, gc_rq->data)) {
 		ret = -EIO;
-		goto err_free_bio;
+		goto err_free_dma;
 	}
 
 	pblk_read_check_rand(pblk, &rqd, gc_rq->lba_list, gc_rq->nr_secs);
@@ -489,8 +475,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
 	pblk_free_rqd_meta(pblk, &rqd);
 	return ret;
 
-err_free_bio:
-	bio_put(bio);
 err_free_dma:
 	pblk_free_rqd_meta(pblk, &rqd);
 	return ret;
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
index e6dda04de144..d5e210c3c5b7 100644
--- a/drivers/lightnvm/pblk-recovery.c
+++ b/drivers/lightnvm/pblk-recovery.c
@@ -178,12 +178,11 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
 	void *meta_list;
 	struct pblk_pad_rq *pad_rq;
 	struct nvm_rq *rqd;
-	struct bio *bio;
 	struct ppa_addr *ppa_list;
 	void *data;
 	__le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
 	u64 w_ptr = line->cur_sec;
-	int left_line_ppas, rq_ppas, rq_len;
+	int left_line_ppas, rq_ppas;
 	int i, j;
 	int ret = 0;
 
@@ -212,28 +211,15 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
 		goto fail_complete;
 	}
 
-	rq_len = rq_ppas * geo->csecs;
-
-	bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
-						PBLK_VMALLOC_META, GFP_KERNEL);
-	if (IS_ERR(bio)) {
-		ret = PTR_ERR(bio);
-		goto fail_complete;
-	}
-
-	bio->bi_iter.bi_sector = 0; /* internal bio */
-	bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
-
 	rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT);
 
 	ret = pblk_alloc_rqd_meta(pblk, rqd);
 	if (ret) {
 		pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
-		bio_put(bio);
 		goto fail_complete;
 	}
 
-	rqd->bio = bio;
+	rqd->bio = NULL;
 	rqd->opcode = NVM_OP_PWRITE;
 	rqd->is_seq = 1;
 	rqd->nr_ppas = rq_ppas;
@@ -275,13 +261,12 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
 	kref_get(&pad_rq->ref);
 	pblk_down_chunk(pblk, ppa_list[0]);
 
-	ret = pblk_submit_io(pblk, rqd);
+	ret = pblk_submit_io(pblk, rqd, data);
 	if (ret) {
 		pblk_err(pblk, "I/O submission failed: %d\n", ret);
 		pblk_up_chunk(pblk, ppa_list[0]);
 		kref_put(&pad_rq->ref, pblk_recov_complete);
 		pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
-		bio_put(bio);
 		goto fail_complete;
 	}
 
@@ -375,7 +360,6 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
 	struct ppa_addr *ppa_list;
 	void *meta_list;
 	struct nvm_rq *rqd;
-	struct bio *bio;
 	void *data;
 	dma_addr_t dma_ppa_list, dma_meta_list;
 	__le64 *lba_list;
@@ -407,15 +391,7 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
 	rq_len = rq_ppas * geo->csecs;
 
 retry_rq:
-	bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL);
-	if (IS_ERR(bio))
-		return PTR_ERR(bio);
-
-	bio->bi_iter.bi_sector = 0; /* internal bio */
-	bio_set_op_attrs(bio, REQ_OP_READ, 0);
-	bio_get(bio);
-
-	rqd->bio = bio;
+	rqd->bio = NULL;
 	rqd->opcode = NVM_OP_PREAD;
 	rqd->meta_list = meta_list;
 	rqd->nr_ppas = rq_ppas;
@@ -445,10 +421,9 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
 				addr_to_gen_ppa(pblk, paddr + j, line->id);
 	}
 
-	ret = pblk_submit_io_sync(pblk, rqd);
+	ret = pblk_submit_io_sync(pblk, rqd, data);
 	if (ret) {
 		pblk_err(pblk, "I/O submission failed: %d\n", ret);
-		bio_put(bio);
 		return ret;
 	}
 
@@ -460,24 +435,20 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
 
 		if (padded) {
 			pblk_log_read_err(pblk, rqd);
-			bio_put(bio);
 			return -EINTR;
 		}
 
 		pad_distance = pblk_pad_distance(pblk, line);
 		ret = pblk_recov_pad_line(pblk, line, pad_distance);
 		if (ret) {
-			bio_put(bio);
 			return ret;
 		}
 
 		padded = true;
-		bio_put(bio);
 		goto retry_rq;
 	}
 
 	pblk_get_packed_meta(pblk, rqd);
-	bio_put(bio);
 
 	for (i = 0; i < rqd->nr_ppas; i++) {
 		struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i);
diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
index 4e63f9b5954c..b9a2aeba95ab 100644
--- a/drivers/lightnvm/pblk-write.c
+++ b/drivers/lightnvm/pblk-write.c
@@ -373,7 +373,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
 	struct pblk_emeta *emeta = meta_line->emeta;
 	struct ppa_addr *ppa_list;
 	struct pblk_g_ctx *m_ctx;
-	struct bio *bio;
 	struct nvm_rq *rqd;
 	void *data;
 	u64 paddr;
@@ -391,20 +390,9 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
 	rq_len = rq_ppas * geo->csecs;
 	data = ((void *)emeta->buf) + emeta->mem;
 
-	bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
-					l_mg->emeta_alloc_type, GFP_KERNEL);
-	if (IS_ERR(bio)) {
-		pblk_err(pblk, "failed to map emeta io");
-		ret = PTR_ERR(bio);
-		goto fail_free_rqd;
-	}
-	bio->bi_iter.bi_sector = 0; /* internal bio */
-	bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
-	rqd->bio = bio;
-
 	ret = pblk_alloc_w_rq(pblk, rqd, rq_ppas, pblk_end_io_write_meta);
 	if (ret)
-		goto fail_free_bio;
+		goto fail_free_rqd;
 
 	ppa_list = nvm_rq_to_ppa_list(rqd);
 	for (i = 0; i < rqd->nr_ppas; ) {
@@ -423,7 +411,7 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
 
 	pblk_down_chunk(pblk, ppa_list[0]);
 
-	ret = pblk_submit_io(pblk, rqd);
+	ret = pblk_submit_io(pblk, rqd, data);
 	if (ret) {
 		pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
 		goto fail_rollback;
@@ -437,8 +425,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
 	pblk_dealloc_page(pblk, meta_line, rq_ppas);
 	list_add(&meta_line->list, &meta_line->list);
 	spin_unlock(&l_mg->close_lock);
-fail_free_bio:
-	bio_put(bio);
 fail_free_rqd:
 	pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
 	return ret;
@@ -523,7 +509,7 @@ static int pblk_submit_io_set(struct pblk *pblk, struct nvm_rq *rqd)
 	meta_line = pblk_should_submit_meta_io(pblk, rqd);
 
 	/* Submit data write for current data line */
-	err = pblk_submit_io(pblk, rqd);
+	err = pblk_submit_io(pblk, rqd, NULL);
 	if (err) {
 		pblk_err(pblk, "data I/O submission failed: %d\n", err);
 		return NVM_IO_ERR;
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index a67855387f53..d515d3409a74 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -783,14 +783,10 @@ struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk,
 					      struct ppa_addr ppa);
 void pblk_log_write_err(struct pblk *pblk, struct nvm_rq *rqd);
 void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd);
-int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
-int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd);
-int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd);
+int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
+int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
 int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line);
 void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd);
-struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
-			      unsigned int nr_secs, unsigned int len,
-			      int alloc_type, gfp_t gfp_mask);
 struct pblk_line *pblk_line_get(struct pblk *pblk);
 struct pblk_line *pblk_line_get_first_data(struct pblk *pblk);
 struct pblk_line *pblk_line_replace_data(struct pblk *pblk);
diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index d6f121452d5d..ec46693f6b64 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -667,11 +667,14 @@ static struct request *nvme_nvm_alloc_request(struct request_queue *q,
 	return rq;
 }
 
-static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
+static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd,
+			      void *buf)
 {
+	struct nvm_geo *geo = &dev->geo;
 	struct request_queue *q = dev->q;
 	struct nvme_nvm_command *cmd;
 	struct request *rq;
+	int ret;
 
 	cmd = kzalloc(sizeof(struct nvme_nvm_command), GFP_KERNEL);
 	if (!cmd)
@@ -679,8 +682,15 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 
 	rq = nvme_nvm_alloc_request(q, rqd, cmd);
 	if (IS_ERR(rq)) {
-		kfree(cmd);
-		return PTR_ERR(rq);
+		ret = PTR_ERR(rq);
+		goto err_free_cmd;
+	}
+
+	if (buf) {
+		ret = blk_rq_map_kern(q, rq, buf, geo->csecs * rqd->nr_ppas,
+				GFP_KERNEL);
+		if (ret)
+			goto err_free_cmd;
 	}
 
 	rq->end_io_data = rqd;
@@ -688,6 +698,10 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 	blk_execute_rq_nowait(q, NULL, rq, 0, nvme_nvm_end_io);
 
 	return 0;
+
+err_free_cmd:
+	kfree(cmd);
+	return ret;
 }
 
 static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name,
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index 8891647b24b1..ee8ec2e68055 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -88,7 +88,7 @@ typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *);
 typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
 typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, sector_t, int,
 							struct nvm_chk_meta *);
-typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *, void *);
 typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *, int);
 typedef void (nvm_destroy_dma_pool_fn)(void *);
 typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
@@ -680,8 +680,8 @@ extern int nvm_get_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr,
 			      int, struct nvm_chk_meta *);
 extern int nvm_set_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr *,
 			      int, int);
-extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *);
-extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *);
+extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *, void *);
+extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *, void *);
 extern void nvm_end_io(struct nvm_rq *);
 
 #else /* CONFIG_NVM */
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata
  2019-07-31  9:41 [PATCH 0/4] lnvm/pblk mapping cleanups Hans Holmberg
  2019-07-31  9:41 ` [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn Hans Holmberg
  2019-07-31  9:41 ` [PATCH 2/4] lightnvm: move metadata mapping to lower level driver Hans Holmberg
@ 2019-07-31  9:41 ` Hans Holmberg
  2019-07-31 14:00   ` Javier González
  2019-08-06  7:06   ` Christoph Hellwig
  2019-07-31  9:41 ` [PATCH 4/4] block: stop exporting bio_map_kern Hans Holmberg
  2019-08-06 13:40 ` [PATCH 0/4] lnvm/pblk mapping cleanups Matias Bjørling
  4 siblings, 2 replies; 17+ messages in thread
From: Hans Holmberg @ 2019-07-31  9:41 UTC (permalink / raw)
  To: Matias Bjorling
  Cc: Christoph Hellwig, Javier González, linux-block,
	linux-kernel, Hans Holmberg

There is no reason now not to use kvmalloc, so
so replace the internal metadata allocation scheme.

Signed-off-by: Hans Holmberg <hans@owltronix.com>
---
 drivers/lightnvm/pblk-core.c |  3 +--
 drivers/lightnvm/pblk-gc.c   | 19 ++++++++-----------
 drivers/lightnvm/pblk-init.c | 38 ++++++++++----------------------------
 drivers/lightnvm/pblk.h      | 23 -----------------------
 4 files changed, 19 insertions(+), 64 deletions(-)

diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index a58d3c84a3f2..b413bafe93fd 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1839,8 +1839,7 @@ static void pblk_save_lba_list(struct pblk *pblk, struct pblk_line *line)
 	struct pblk_w_err_gc *w_err_gc = line->w_err_gc;
 	struct pblk_emeta *emeta = line->emeta;
 
-	w_err_gc->lba_list = pblk_malloc(lba_list_size,
-					 l_mg->emeta_alloc_type, GFP_KERNEL);
+	w_err_gc->lba_list = kvmalloc(lba_list_size, GFP_KERNEL);
 	memcpy(w_err_gc->lba_list, emeta_to_lbas(pblk, emeta->buf),
 				lba_list_size);
 }
diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c
index 63ee205b41c4..2581eebcfc41 100644
--- a/drivers/lightnvm/pblk-gc.c
+++ b/drivers/lightnvm/pblk-gc.c
@@ -132,14 +132,12 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
 				       struct pblk_line *line)
 {
 	struct line_emeta *emeta_buf;
-	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	struct pblk_line_meta *lm = &pblk->lm;
 	unsigned int lba_list_size = lm->emeta_len[2];
 	__le64 *lba_list;
 	int ret;
 
-	emeta_buf = pblk_malloc(lm->emeta_len[0],
-				l_mg->emeta_alloc_type, GFP_KERNEL);
+	emeta_buf = kvmalloc(lm->emeta_len[0], GFP_KERNEL);
 	if (!emeta_buf)
 		return NULL;
 
@@ -147,7 +145,7 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
 	if (ret) {
 		pblk_err(pblk, "line %d read emeta failed (%d)\n",
 				line->id, ret);
-		pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
+		kvfree(emeta_buf);
 		return NULL;
 	}
 
@@ -161,16 +159,16 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
 	if (ret) {
 		pblk_err(pblk, "inconsistent emeta (line %d)\n",
 				line->id);
-		pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
+		kvfree(emeta_buf);
 		return NULL;
 	}
 
-	lba_list = pblk_malloc(lba_list_size,
-			       l_mg->emeta_alloc_type, GFP_KERNEL);
+	lba_list = kvmalloc(lba_list_size, GFP_KERNEL);
+
 	if (lba_list)
 		memcpy(lba_list, emeta_to_lbas(pblk, emeta_buf), lba_list_size);
 
-	pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
+	kvfree(emeta_buf);
 
 	return lba_list;
 }
@@ -181,7 +179,6 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
 									ws);
 	struct pblk *pblk = line_ws->pblk;
 	struct pblk_line *line = line_ws->line;
-	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	struct pblk_line_meta *lm = &pblk->lm;
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
@@ -272,7 +269,7 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
 		goto next_rq;
 
 out:
-	pblk_mfree(lba_list, l_mg->emeta_alloc_type);
+	kvfree(lba_list);
 	kfree(line_ws);
 	kfree(invalid_bitmap);
 
@@ -286,7 +283,7 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
 fail_free_gc_rq:
 	kfree(gc_rq);
 fail_free_lba_list:
-	pblk_mfree(lba_list, l_mg->emeta_alloc_type);
+	kvfree(lba_list);
 fail_free_invalid_bitmap:
 	kfree(invalid_bitmap);
 fail_free_ws:
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index b351c7f002de..9a967a2e83dd 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -543,7 +543,7 @@ static void pblk_line_mg_free(struct pblk *pblk)
 
 	for (i = 0; i < PBLK_DATA_LINES; i++) {
 		kfree(l_mg->sline_meta[i]);
-		pblk_mfree(l_mg->eline_meta[i]->buf, l_mg->emeta_alloc_type);
+		kvfree(l_mg->eline_meta[i]->buf);
 		kfree(l_mg->eline_meta[i]);
 	}
 
@@ -560,7 +560,7 @@ static void pblk_line_meta_free(struct pblk_line_mgmt *l_mg,
 	kfree(line->erase_bitmap);
 	kfree(line->chks);
 
-	pblk_mfree(w_err_gc->lba_list, l_mg->emeta_alloc_type);
+	kvfree(w_err_gc->lba_list);
 	kfree(w_err_gc);
 }
 
@@ -890,29 +890,14 @@ static int pblk_line_mg_init(struct pblk *pblk)
 		if (!emeta)
 			goto fail_free_emeta;
 
-		if (lm->emeta_len[0] > KMALLOC_MAX_CACHE_SIZE) {
-			l_mg->emeta_alloc_type = PBLK_VMALLOC_META;
-
-			emeta->buf = vmalloc(lm->emeta_len[0]);
-			if (!emeta->buf) {
-				kfree(emeta);
-				goto fail_free_emeta;
-			}
-
-			emeta->nr_entries = lm->emeta_sec[0];
-			l_mg->eline_meta[i] = emeta;
-		} else {
-			l_mg->emeta_alloc_type = PBLK_KMALLOC_META;
-
-			emeta->buf = kmalloc(lm->emeta_len[0], GFP_KERNEL);
-			if (!emeta->buf) {
-				kfree(emeta);
-				goto fail_free_emeta;
-			}
-
-			emeta->nr_entries = lm->emeta_sec[0];
-			l_mg->eline_meta[i] = emeta;
+		emeta->buf = kvmalloc(lm->emeta_len[0], GFP_KERNEL);
+		if (!emeta->buf) {
+			kfree(emeta);
+			goto fail_free_emeta;
 		}
+
+		emeta->nr_entries = lm->emeta_sec[0];
+		l_mg->eline_meta[i] = emeta;
 	}
 
 	for (i = 0; i < l_mg->nr_lines; i++)
@@ -926,10 +911,7 @@ static int pblk_line_mg_init(struct pblk *pblk)
 
 fail_free_emeta:
 	while (--i >= 0) {
-		if (l_mg->emeta_alloc_type == PBLK_VMALLOC_META)
-			vfree(l_mg->eline_meta[i]->buf);
-		else
-			kfree(l_mg->eline_meta[i]->buf);
+		kvfree(l_mg->eline_meta[i]->buf);
 		kfree(l_mg->eline_meta[i]);
 	}
 
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index d515d3409a74..86ffa875bfe1 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -482,11 +482,6 @@ struct pblk_line {
 #define PBLK_DATA_LINES 4
 
 enum {
-	PBLK_KMALLOC_META = 1,
-	PBLK_VMALLOC_META = 2,
-};
-
-enum {
 	PBLK_EMETA_TYPE_HEADER = 1,	/* struct line_emeta first sector */
 	PBLK_EMETA_TYPE_LLBA = 2,	/* lba list - type: __le64 */
 	PBLK_EMETA_TYPE_VSC = 3,	/* vsc list - type: __le32 */
@@ -521,9 +516,6 @@ struct pblk_line_mgmt {
 
 	__le32 *vsc_list;		/* Valid sector counts for all lines */
 
-	/* Metadata allocation type: VMALLOC | KMALLOC */
-	int emeta_alloc_type;
-
 	/* Pre-allocated metadata for data lines */
 	struct pblk_smeta *sline_meta[PBLK_DATA_LINES];
 	struct pblk_emeta *eline_meta[PBLK_DATA_LINES];
@@ -934,21 +926,6 @@ void pblk_rl_werr_line_out(struct pblk_rl *rl);
 int pblk_sysfs_init(struct gendisk *tdisk);
 void pblk_sysfs_exit(struct gendisk *tdisk);
 
-static inline void *pblk_malloc(size_t size, int type, gfp_t flags)
-{
-	if (type == PBLK_KMALLOC_META)
-		return kmalloc(size, flags);
-	return vmalloc(size);
-}
-
-static inline void pblk_mfree(void *ptr, int type)
-{
-	if (type == PBLK_KMALLOC_META)
-		kfree(ptr);
-	else
-		vfree(ptr);
-}
-
 static inline struct nvm_rq *nvm_rq_from_c_ctx(void *c_ctx)
 {
 	return c_ctx - sizeof(struct nvm_rq);
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 4/4] block: stop exporting bio_map_kern
  2019-07-31  9:41 [PATCH 0/4] lnvm/pblk mapping cleanups Hans Holmberg
                   ` (2 preceding siblings ...)
  2019-07-31  9:41 ` [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata Hans Holmberg
@ 2019-07-31  9:41 ` Hans Holmberg
  2019-07-31 17:13   ` Javier González
  2019-08-06  7:07   ` Christoph Hellwig
  2019-08-06 13:40 ` [PATCH 0/4] lnvm/pblk mapping cleanups Matias Bjørling
  4 siblings, 2 replies; 17+ messages in thread
From: Hans Holmberg @ 2019-07-31  9:41 UTC (permalink / raw)
  To: Matias Bjorling
  Cc: Christoph Hellwig, Javier González, linux-block,
	linux-kernel, Hans Holmberg

Now that there no module users left of bio_map_kern, stop
exporting the symbol.

Signed-off-by: Hans Holmberg <hans@owltronix.com>
---
 block/bio.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/block/bio.c b/block/bio.c
index 299a0e7651ec..96ca0b4e73bb 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1521,7 +1521,6 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
 	bio->bi_end_io = bio_map_kern_endio;
 	return bio;
 }
-EXPORT_SYMBOL(bio_map_kern);
 
 static void bio_copy_kern_endio(struct bio *bio)
 {
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn
  2019-07-31  9:41 ` [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn Hans Holmberg
@ 2019-07-31 13:54   ` Javier González
  2019-08-06  7:05   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Javier González @ 2019-07-31 13:54 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjørling, Christoph Hellwig, linux-block, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5013 bytes --]

> On 31 Jul 2019, at 11.41, Hans Holmberg <hans@owltronix.com> wrote:
> 
> Move the redundant sync handling interface and wait for a completion
> in the lightnvm core instead.
> 
> Signed-off-by: Hans Holmberg <hans@owltronix.com>
> ---
> drivers/lightnvm/core.c      | 35 +++++++++++++++++++++++++++++------
> drivers/nvme/host/lightnvm.c | 29 -----------------------------
> include/linux/lightnvm.h     |  2 --
> 3 files changed, 29 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
> index a600934fdd9c..01d098fb96ac 100644
> --- a/drivers/lightnvm/core.c
> +++ b/drivers/lightnvm/core.c
> @@ -752,12 +752,36 @@ int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> }
> EXPORT_SYMBOL(nvm_submit_io);
> 
> +static void nvm_sync_end_io(struct nvm_rq *rqd)
> +{
> +	struct completion *waiting = rqd->private;
> +
> +	complete(waiting);
> +}
> +
> +static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
> +{
> +	DECLARE_COMPLETION_ONSTACK(wait);
> +	int ret = 0;
> +
> +	rqd->end_io = nvm_sync_end_io;
> +	rqd->private = &wait;
> +
> +	ret = dev->ops->submit_io(dev, rqd);
> +	if (ret)
> +		return ret;
> +
> +	wait_for_completion_io(&wait);
> +
> +	return 0;
> +}
> +
> int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> {
> 	struct nvm_dev *dev = tgt_dev->parent;
> 	int ret;
> 
> -	if (!dev->ops->submit_io_sync)
> +	if (!dev->ops->submit_io)
> 		return -ENODEV;
> 
> 	nvm_rq_tgt_to_dev(tgt_dev, rqd);
> @@ -765,9 +789,7 @@ int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> 	rqd->dev = tgt_dev;
> 	rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
> 
> -	/* In case of error, fail with right address format */
> -	ret = dev->ops->submit_io_sync(dev, rqd);
> -	nvm_rq_dev_to_tgt(tgt_dev, rqd);
> +	ret = nvm_submit_io_wait(dev, rqd);
> 
> 	return ret;
> }
> @@ -788,12 +810,13 @@ EXPORT_SYMBOL(nvm_end_io);
> 
> static int nvm_submit_io_sync_raw(struct nvm_dev *dev, struct nvm_rq *rqd)
> {
> -	if (!dev->ops->submit_io_sync)
> +	if (!dev->ops->submit_io)
> 		return -ENODEV;
> 
> +	rqd->dev = NULL;
> 	rqd->flags = nvm_set_flags(&dev->geo, rqd);
> 
> -	return dev->ops->submit_io_sync(dev, rqd);
> +	return nvm_submit_io_wait(dev, rqd);
> }
> 
> static int nvm_bb_chunk_sense(struct nvm_dev *dev, struct ppa_addr ppa)
> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
> index ba009d4c9dfa..d6f121452d5d 100644
> --- a/drivers/nvme/host/lightnvm.c
> +++ b/drivers/nvme/host/lightnvm.c
> @@ -690,34 +690,6 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
> 	return 0;
> }
> 
> -static int nvme_nvm_submit_io_sync(struct nvm_dev *dev, struct nvm_rq *rqd)
> -{
> -	struct request_queue *q = dev->q;
> -	struct request *rq;
> -	struct nvme_nvm_command cmd;
> -	int ret = 0;
> -
> -	memset(&cmd, 0, sizeof(struct nvme_nvm_command));
> -
> -	rq = nvme_nvm_alloc_request(q, rqd, &cmd);
> -	if (IS_ERR(rq))
> -		return PTR_ERR(rq);
> -
> -	/* I/Os can fail and the error is signaled through rqd. Callers must
> -	 * handle the error accordingly.
> -	 */
> -	blk_execute_rq(q, NULL, rq, 0);
> -	if (nvme_req(rq)->flags & NVME_REQ_CANCELLED)
> -		ret = -EINTR;
> -
> -	rqd->ppa_status = le64_to_cpu(nvme_req(rq)->result.u64);
> -	rqd->error = nvme_req(rq)->status;
> -
> -	blk_mq_free_request(rq);
> -
> -	return ret;
> -}
> -
> static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name,
> 					int size)
> {
> @@ -754,7 +726,6 @@ static struct nvm_dev_ops nvme_nvm_dev_ops = {
> 	.get_chk_meta		= nvme_nvm_get_chk_meta,
> 
> 	.submit_io		= nvme_nvm_submit_io,
> -	.submit_io_sync		= nvme_nvm_submit_io_sync,
> 
> 	.create_dma_pool	= nvme_nvm_create_dma_pool,
> 	.destroy_dma_pool	= nvme_nvm_destroy_dma_pool,
> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
> index 4d0d5655c7b2..8891647b24b1 100644
> --- a/include/linux/lightnvm.h
> +++ b/include/linux/lightnvm.h
> @@ -89,7 +89,6 @@ typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
> typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, sector_t, int,
> 							struct nvm_chk_meta *);
> typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
> -typedef int (nvm_submit_io_sync_fn)(struct nvm_dev *, struct nvm_rq *);
> typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *, int);
> typedef void (nvm_destroy_dma_pool_fn)(void *);
> typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
> @@ -104,7 +103,6 @@ struct nvm_dev_ops {
> 	nvm_get_chk_meta_fn	*get_chk_meta;
> 
> 	nvm_submit_io_fn	*submit_io;
> -	nvm_submit_io_sync_fn	*submit_io_sync;
> 
> 	nvm_create_dma_pool_fn	*create_dma_pool;
> 	nvm_destroy_dma_pool_fn	*destroy_dma_pool;
> --
> 2.7.4

Looks good to me. Thanks Hans.

Reviewed-by: Javier González <javier@javigon.com>


[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/4] lightnvm: move metadata mapping to lower level driver
  2019-07-31  9:41 ` [PATCH 2/4] lightnvm: move metadata mapping to lower level driver Hans Holmberg
@ 2019-07-31 13:58   ` Javier González
  2019-08-01  7:15     ` Hans Holmberg
  2019-08-06  7:06   ` Christoph Hellwig
  1 sibling, 1 reply; 17+ messages in thread
From: Javier González @ 2019-07-31 13:58 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjørling, Christoph Hellwig, linux-block, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 24892 bytes --]

> On 31 Jul 2019, at 11.41, Hans Holmberg <hans@owltronix.com> wrote:
> 
> Now that blk_rq_map_kern can map both kmem and vmem, move
> internal metadata mapping down to the lower level driver.
> 
> Signed-off-by: Hans Holmberg <hans@owltronix.com>
> ---
> drivers/lightnvm/core.c          |  16 +++---
> drivers/lightnvm/pblk-core.c     | 113 +++++----------------------------------
> drivers/lightnvm/pblk-read.c     |  22 ++------
> drivers/lightnvm/pblk-recovery.c |  39 ++------------
> drivers/lightnvm/pblk-write.c    |  20 ++-----
> drivers/lightnvm/pblk.h          |   8 +--
> drivers/nvme/host/lightnvm.c     |  20 +++++--
> include/linux/lightnvm.h         |   6 +--
> 8 files changed, 54 insertions(+), 190 deletions(-)
> 
> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
> index 01d098fb96ac..3cd03582a2ed 100644
> --- a/drivers/lightnvm/core.c
> +++ b/drivers/lightnvm/core.c
> @@ -731,7 +731,7 @@ static int nvm_set_flags(struct nvm_geo *geo, struct nvm_rq *rqd)
> 	return flags;
> }
> 
> -int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> +int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd, void *buf)
> {
> 	struct nvm_dev *dev = tgt_dev->parent;
> 	int ret;
> @@ -745,7 +745,7 @@ int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> 	rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
> 
> 	/* In case of error, fail with right address format */
> -	ret = dev->ops->submit_io(dev, rqd);
> +	ret = dev->ops->submit_io(dev, rqd, buf);
> 	if (ret)
> 		nvm_rq_dev_to_tgt(tgt_dev, rqd);
> 	return ret;
> @@ -759,7 +759,8 @@ static void nvm_sync_end_io(struct nvm_rq *rqd)
> 	complete(waiting);
> }
> 
> -static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
> +static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd,
> +			      void *buf)
> {
> 	DECLARE_COMPLETION_ONSTACK(wait);
> 	int ret = 0;
> @@ -767,7 +768,7 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
> 	rqd->end_io = nvm_sync_end_io;
> 	rqd->private = &wait;
> 
> -	ret = dev->ops->submit_io(dev, rqd);
> +	ret = dev->ops->submit_io(dev, rqd, buf);
> 	if (ret)
> 		return ret;
> 
> @@ -776,7 +777,8 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
> 	return 0;
> }
> 
> -int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> +int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd,
> +		       void *buf)
> {
> 	struct nvm_dev *dev = tgt_dev->parent;
> 	int ret;
> @@ -789,7 +791,7 @@ int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> 	rqd->dev = tgt_dev;
> 	rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
> 
> -	ret = nvm_submit_io_wait(dev, rqd);
> +	ret = nvm_submit_io_wait(dev, rqd, buf);
> 
> 	return ret;
> }
> @@ -816,7 +818,7 @@ static int nvm_submit_io_sync_raw(struct nvm_dev *dev, struct nvm_rq *rqd)
> 	rqd->dev = NULL;
> 	rqd->flags = nvm_set_flags(&dev->geo, rqd);
> 
> -	return nvm_submit_io_wait(dev, rqd);
> +	return nvm_submit_io_wait(dev, rqd, NULL);
> }
> 
> static int nvm_bb_chunk_sense(struct nvm_dev *dev, struct ppa_addr ppa)
> diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
> index f546e6f28b8a..a58d3c84a3f2 100644
> --- a/drivers/lightnvm/pblk-core.c
> +++ b/drivers/lightnvm/pblk-core.c
> @@ -507,7 +507,7 @@ void pblk_set_sec_per_write(struct pblk *pblk, int sec_per_write)
> 	pblk->sec_per_write = sec_per_write;
> }
> 
> -int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
> +int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
> {
> 	struct nvm_tgt_dev *dev = pblk->dev;
> 
> @@ -518,7 +518,7 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
> 		return NVM_IO_ERR;
> #endif
> 
> -	return nvm_submit_io(dev, rqd);
> +	return nvm_submit_io(dev, rqd, buf);
> }
> 
> void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
> @@ -541,7 +541,7 @@ void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
> 	}
> }
> 
> -int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
> +int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
> {
> 	struct nvm_tgt_dev *dev = pblk->dev;
> 	int ret;
> @@ -553,7 +553,7 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
> 		return NVM_IO_ERR;
> #endif
> 
> -	ret = nvm_submit_io_sync(dev, rqd);
> +	ret = nvm_submit_io_sync(dev, rqd, buf);
> 
> 	if (trace_pblk_chunk_state_enabled() && !ret &&
> 	    rqd->opcode == NVM_OP_PWRITE)
> @@ -562,65 +562,19 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
> 	return ret;
> }
> 
> -int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd)
> +static int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd,
> +				   void *buf)
> {
> 	struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
> 	int ret;
> 
> 	pblk_down_chunk(pblk, ppa_list[0]);
> -	ret = pblk_submit_io_sync(pblk, rqd);
> +	ret = pblk_submit_io_sync(pblk, rqd, buf);
> 	pblk_up_chunk(pblk, ppa_list[0]);
> 
> 	return ret;
> }
> 
> -static void pblk_bio_map_addr_endio(struct bio *bio)
> -{
> -	bio_put(bio);
> -}
> -
> -struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
> -			      unsigned int nr_secs, unsigned int len,
> -			      int alloc_type, gfp_t gfp_mask)
> -{
> -	struct nvm_tgt_dev *dev = pblk->dev;
> -	void *kaddr = data;
> -	struct page *page;
> -	struct bio *bio;
> -	int i, ret;
> -
> -	if (alloc_type == PBLK_KMALLOC_META)
> -		return bio_map_kern(dev->q, kaddr, len, gfp_mask);
> -
> -	bio = bio_kmalloc(gfp_mask, nr_secs);
> -	if (!bio)
> -		return ERR_PTR(-ENOMEM);
> -
> -	for (i = 0; i < nr_secs; i++) {
> -		page = vmalloc_to_page(kaddr);
> -		if (!page) {
> -			pblk_err(pblk, "could not map vmalloc bio\n");
> -			bio_put(bio);
> -			bio = ERR_PTR(-ENOMEM);
> -			goto out;
> -		}
> -
> -		ret = bio_add_pc_page(dev->q, bio, page, PAGE_SIZE, 0);
> -		if (ret != PAGE_SIZE) {
> -			pblk_err(pblk, "could not add page to bio\n");
> -			bio_put(bio);
> -			bio = ERR_PTR(-ENOMEM);
> -			goto out;
> -		}
> -
> -		kaddr += PAGE_SIZE;
> -	}
> -
> -	bio->bi_end_io = pblk_bio_map_addr_endio;
> -out:
> -	return bio;
> -}
> -
> int pblk_calc_secs(struct pblk *pblk, unsigned long secs_avail,
> 		   unsigned long secs_to_flush, bool skip_meta)
> {
> @@ -722,9 +676,7 @@ u64 pblk_line_smeta_start(struct pblk *pblk, struct pblk_line *line)
> 
> int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> {
> -	struct nvm_tgt_dev *dev = pblk->dev;
> 	struct pblk_line_meta *lm = &pblk->lm;
> -	struct bio *bio;
> 	struct ppa_addr *ppa_list;
> 	struct nvm_rq rqd;
> 	u64 paddr = pblk_line_smeta_start(pblk, line);
> @@ -736,16 +688,6 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> 	if (ret)
> 		return ret;
> 
> -	bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
> -	if (IS_ERR(bio)) {
> -		ret = PTR_ERR(bio);
> -		goto clear_rqd;
> -	}
> -
> -	bio->bi_iter.bi_sector = 0; /* internal bio */
> -	bio_set_op_attrs(bio, REQ_OP_READ, 0);
> -
> -	rqd.bio = bio;
> 	rqd.opcode = NVM_OP_PREAD;
> 	rqd.nr_ppas = lm->smeta_sec;
> 	rqd.is_seq = 1;
> @@ -754,10 +696,9 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> 	for (i = 0; i < lm->smeta_sec; i++, paddr++)
> 		ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line->id);
> 
> -	ret = pblk_submit_io_sync(pblk, &rqd);
> +	ret = pblk_submit_io_sync(pblk, &rqd, line->smeta);
> 	if (ret) {
> 		pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
> -		bio_put(bio);
> 		goto clear_rqd;
> 	}
> 
> @@ -776,9 +717,7 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
> 				 u64 paddr)
> {
> -	struct nvm_tgt_dev *dev = pblk->dev;
> 	struct pblk_line_meta *lm = &pblk->lm;
> -	struct bio *bio;
> 	struct ppa_addr *ppa_list;
> 	struct nvm_rq rqd;
> 	__le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
> @@ -791,16 +730,6 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
> 	if (ret)
> 		return ret;
> 
> -	bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
> -	if (IS_ERR(bio)) {
> -		ret = PTR_ERR(bio);
> -		goto clear_rqd;
> -	}
> -
> -	bio->bi_iter.bi_sector = 0; /* internal bio */
> -	bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
> -
> -	rqd.bio = bio;
> 	rqd.opcode = NVM_OP_PWRITE;
> 	rqd.nr_ppas = lm->smeta_sec;
> 	rqd.is_seq = 1;
> @@ -814,10 +743,9 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
> 		meta->lba = lba_list[paddr] = addr_empty;
> 	}
> 
> -	ret = pblk_submit_io_sync_sem(pblk, &rqd);
> +	ret = pblk_submit_io_sync_sem(pblk, &rqd, line->smeta);
> 	if (ret) {
> 		pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
> -		bio_put(bio);
> 		goto clear_rqd;
> 	}
> 
> @@ -838,10 +766,8 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> {
> 	struct nvm_tgt_dev *dev = pblk->dev;
> 	struct nvm_geo *geo = &dev->geo;
> -	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> 	struct pblk_line_meta *lm = &pblk->lm;
> 	void *ppa_list_buf, *meta_list;
> -	struct bio *bio;
> 	struct ppa_addr *ppa_list;
> 	struct nvm_rq rqd;
> 	u64 paddr = line->emeta_ssec;
> @@ -867,17 +793,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> 	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
> 	rq_len = rq_ppas * geo->csecs;
> 
> -	bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len,
> -					l_mg->emeta_alloc_type, GFP_KERNEL);
> -	if (IS_ERR(bio)) {
> -		ret = PTR_ERR(bio);
> -		goto free_rqd_dma;
> -	}
> -
> -	bio->bi_iter.bi_sector = 0; /* internal bio */
> -	bio_set_op_attrs(bio, REQ_OP_READ, 0);
> -
> -	rqd.bio = bio;
> 	rqd.meta_list = meta_list;
> 	rqd.ppa_list = ppa_list_buf;
> 	rqd.dma_meta_list = dma_meta_list;
> @@ -896,7 +811,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> 		while (test_bit(pos, line->blk_bitmap)) {
> 			paddr += min;
> 			if (pblk_boundary_paddr_checks(pblk, paddr)) {
> -				bio_put(bio);
> 				ret = -EINTR;
> 				goto free_rqd_dma;
> 			}
> @@ -906,7 +820,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> 		}
> 
> 		if (pblk_boundary_paddr_checks(pblk, paddr + min)) {
> -			bio_put(bio);
> 			ret = -EINTR;
> 			goto free_rqd_dma;
> 		}
> @@ -915,10 +828,9 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> 			ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line_id);
> 	}
> 
> -	ret = pblk_submit_io_sync(pblk, &rqd);
> +	ret = pblk_submit_io_sync(pblk, &rqd, emeta_buf);
> 	if (ret) {
> 		pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
> -		bio_put(bio);
> 		goto free_rqd_dma;
> 	}
> 
> @@ -963,7 +875,7 @@ static int pblk_blk_erase_sync(struct pblk *pblk, struct ppa_addr ppa)
> 	/* The write thread schedules erases so that it minimizes disturbances
> 	 * with writes. Thus, there is no need to take the LUN semaphore.
> 	 */
> -	ret = pblk_submit_io_sync(pblk, &rqd);
> +	ret = pblk_submit_io_sync(pblk, &rqd, NULL);
> 	rqd.private = pblk;
> 	__pblk_end_io_erase(pblk, &rqd);
> 
> @@ -1792,7 +1704,7 @@ int pblk_blk_erase_async(struct pblk *pblk, struct ppa_addr ppa)
> 	/* The write thread schedules erases so that it minimizes disturbances
> 	 * with writes. Thus, there is no need to take the LUN semaphore.
> 	 */
> -	err = pblk_submit_io(pblk, rqd);
> +	err = pblk_submit_io(pblk, rqd, NULL);
> 	if (err) {
> 		struct nvm_tgt_dev *dev = pblk->dev;
> 		struct nvm_geo *geo = &dev->geo;
> @@ -1923,7 +1835,6 @@ void pblk_line_close_meta(struct pblk *pblk, struct pblk_line *line)
> static void pblk_save_lba_list(struct pblk *pblk, struct pblk_line *line)
> {
> 	struct pblk_line_meta *lm = &pblk->lm;
> -	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> 	unsigned int lba_list_size = lm->emeta_len[2];
> 	struct pblk_w_err_gc *w_err_gc = line->w_err_gc;
> 	struct pblk_emeta *emeta = line->emeta;
> diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c
> index d98ea392fe33..d572d4559e4e 100644
> --- a/drivers/lightnvm/pblk-read.c
> +++ b/drivers/lightnvm/pblk-read.c
> @@ -342,7 +342,7 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio)
> 		bio_put(int_bio);
> 		int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set);
> 		goto split_retry;
> -	} else if (pblk_submit_io(pblk, rqd)) {
> +	} else if (pblk_submit_io(pblk, rqd, NULL)) {
> 		/* Submitting IO to drive failed, let's report an error */
> 		rqd->error = -ENODEV;
> 		pblk_end_io_read(rqd);
> @@ -419,7 +419,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
> {
> 	struct nvm_tgt_dev *dev = pblk->dev;
> 	struct nvm_geo *geo = &dev->geo;
> -	struct bio *bio;
> 	struct nvm_rq rqd;
> 	int data_len;
> 	int ret = NVM_IO_OK;
> @@ -447,25 +446,12 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
> 		goto out;
> 
> 	data_len = (gc_rq->secs_to_gc) * geo->csecs;
> -	bio = pblk_bio_map_addr(pblk, gc_rq->data, gc_rq->secs_to_gc, data_len,
> -						PBLK_VMALLOC_META, GFP_KERNEL);
> -	if (IS_ERR(bio)) {
> -		pblk_err(pblk, "could not allocate GC bio (%lu)\n",
> -								PTR_ERR(bio));
> -		ret = PTR_ERR(bio);
> -		goto err_free_dma;
> -	}
> -
> -	bio->bi_iter.bi_sector = 0; /* internal bio */
> -	bio_set_op_attrs(bio, REQ_OP_READ, 0);
> -
> 	rqd.opcode = NVM_OP_PREAD;
> 	rqd.nr_ppas = gc_rq->secs_to_gc;
> -	rqd.bio = bio;
> 
> -	if (pblk_submit_io_sync(pblk, &rqd)) {
> +	if (pblk_submit_io_sync(pblk, &rqd, gc_rq->data)) {
> 		ret = -EIO;
> -		goto err_free_bio;
> +		goto err_free_dma;
> 	}
> 
> 	pblk_read_check_rand(pblk, &rqd, gc_rq->lba_list, gc_rq->nr_secs);
> @@ -489,8 +475,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
> 	pblk_free_rqd_meta(pblk, &rqd);
> 	return ret;
> 
> -err_free_bio:
> -	bio_put(bio);
> err_free_dma:
> 	pblk_free_rqd_meta(pblk, &rqd);
> 	return ret;
> diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
> index e6dda04de144..d5e210c3c5b7 100644
> --- a/drivers/lightnvm/pblk-recovery.c
> +++ b/drivers/lightnvm/pblk-recovery.c
> @@ -178,12 +178,11 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
> 	void *meta_list;
> 	struct pblk_pad_rq *pad_rq;
> 	struct nvm_rq *rqd;
> -	struct bio *bio;
> 	struct ppa_addr *ppa_list;
> 	void *data;
> 	__le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
> 	u64 w_ptr = line->cur_sec;
> -	int left_line_ppas, rq_ppas, rq_len;
> +	int left_line_ppas, rq_ppas;
> 	int i, j;
> 	int ret = 0;
> 
> @@ -212,28 +211,15 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
> 		goto fail_complete;
> 	}
> 
> -	rq_len = rq_ppas * geo->csecs;
> -
> -	bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
> -						PBLK_VMALLOC_META, GFP_KERNEL);
> -	if (IS_ERR(bio)) {
> -		ret = PTR_ERR(bio);
> -		goto fail_complete;
> -	}
> -
> -	bio->bi_iter.bi_sector = 0; /* internal bio */
> -	bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
> -
> 	rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT);
> 
> 	ret = pblk_alloc_rqd_meta(pblk, rqd);
> 	if (ret) {
> 		pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
> -		bio_put(bio);
> 		goto fail_complete;
> 	}
> 
> -	rqd->bio = bio;
> +	rqd->bio = NULL;
> 	rqd->opcode = NVM_OP_PWRITE;
> 	rqd->is_seq = 1;
> 	rqd->nr_ppas = rq_ppas;
> @@ -275,13 +261,12 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
> 	kref_get(&pad_rq->ref);
> 	pblk_down_chunk(pblk, ppa_list[0]);
> 
> -	ret = pblk_submit_io(pblk, rqd);
> +	ret = pblk_submit_io(pblk, rqd, data);
> 	if (ret) {
> 		pblk_err(pblk, "I/O submission failed: %d\n", ret);
> 		pblk_up_chunk(pblk, ppa_list[0]);
> 		kref_put(&pad_rq->ref, pblk_recov_complete);
> 		pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
> -		bio_put(bio);
> 		goto fail_complete;
> 	}
> 
> @@ -375,7 +360,6 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> 	struct ppa_addr *ppa_list;
> 	void *meta_list;
> 	struct nvm_rq *rqd;
> -	struct bio *bio;
> 	void *data;
> 	dma_addr_t dma_ppa_list, dma_meta_list;
> 	__le64 *lba_list;
> @@ -407,15 +391,7 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> 	rq_len = rq_ppas * geo->csecs;
> 
> retry_rq:
> -	bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL);
> -	if (IS_ERR(bio))
> -		return PTR_ERR(bio);
> -
> -	bio->bi_iter.bi_sector = 0; /* internal bio */
> -	bio_set_op_attrs(bio, REQ_OP_READ, 0);
> -	bio_get(bio);
> -
> -	rqd->bio = bio;
> +	rqd->bio = NULL;
> 	rqd->opcode = NVM_OP_PREAD;
> 	rqd->meta_list = meta_list;
> 	rqd->nr_ppas = rq_ppas;
> @@ -445,10 +421,9 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> 				addr_to_gen_ppa(pblk, paddr + j, line->id);
> 	}
> 
> -	ret = pblk_submit_io_sync(pblk, rqd);
> +	ret = pblk_submit_io_sync(pblk, rqd, data);
> 	if (ret) {
> 		pblk_err(pblk, "I/O submission failed: %d\n", ret);
> -		bio_put(bio);
> 		return ret;
> 	}
> 
> @@ -460,24 +435,20 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> 
> 		if (padded) {
> 			pblk_log_read_err(pblk, rqd);
> -			bio_put(bio);
> 			return -EINTR;
> 		}
> 
> 		pad_distance = pblk_pad_distance(pblk, line);
> 		ret = pblk_recov_pad_line(pblk, line, pad_distance);
> 		if (ret) {
> -			bio_put(bio);
> 			return ret;
> 		}
> 
> 		padded = true;
> -		bio_put(bio);
> 		goto retry_rq;
> 	}
> 
> 	pblk_get_packed_meta(pblk, rqd);
> -	bio_put(bio);
> 
> 	for (i = 0; i < rqd->nr_ppas; i++) {
> 		struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i);
> diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
> index 4e63f9b5954c..b9a2aeba95ab 100644
> --- a/drivers/lightnvm/pblk-write.c
> +++ b/drivers/lightnvm/pblk-write.c
> @@ -373,7 +373,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> 	struct pblk_emeta *emeta = meta_line->emeta;
> 	struct ppa_addr *ppa_list;
> 	struct pblk_g_ctx *m_ctx;
> -	struct bio *bio;
> 	struct nvm_rq *rqd;
> 	void *data;
> 	u64 paddr;
> @@ -391,20 +390,9 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> 	rq_len = rq_ppas * geo->csecs;
> 	data = ((void *)emeta->buf) + emeta->mem;
> 
> -	bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
> -					l_mg->emeta_alloc_type, GFP_KERNEL);
> -	if (IS_ERR(bio)) {
> -		pblk_err(pblk, "failed to map emeta io");
> -		ret = PTR_ERR(bio);
> -		goto fail_free_rqd;
> -	}
> -	bio->bi_iter.bi_sector = 0; /* internal bio */
> -	bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
> -	rqd->bio = bio;
> -
> 	ret = pblk_alloc_w_rq(pblk, rqd, rq_ppas, pblk_end_io_write_meta);
> 	if (ret)
> -		goto fail_free_bio;
> +		goto fail_free_rqd;
> 
> 	ppa_list = nvm_rq_to_ppa_list(rqd);
> 	for (i = 0; i < rqd->nr_ppas; ) {
> @@ -423,7 +411,7 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> 
> 	pblk_down_chunk(pblk, ppa_list[0]);
> 
> -	ret = pblk_submit_io(pblk, rqd);
> +	ret = pblk_submit_io(pblk, rqd, data);
> 	if (ret) {
> 		pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
> 		goto fail_rollback;
> @@ -437,8 +425,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> 	pblk_dealloc_page(pblk, meta_line, rq_ppas);
> 	list_add(&meta_line->list, &meta_line->list);
> 	spin_unlock(&l_mg->close_lock);
> -fail_free_bio:
> -	bio_put(bio);
> fail_free_rqd:
> 	pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
> 	return ret;
> @@ -523,7 +509,7 @@ static int pblk_submit_io_set(struct pblk *pblk, struct nvm_rq *rqd)
> 	meta_line = pblk_should_submit_meta_io(pblk, rqd);
> 
> 	/* Submit data write for current data line */
> -	err = pblk_submit_io(pblk, rqd);
> +	err = pblk_submit_io(pblk, rqd, NULL);
> 	if (err) {
> 		pblk_err(pblk, "data I/O submission failed: %d\n", err);
> 		return NVM_IO_ERR;
> diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
> index a67855387f53..d515d3409a74 100644
> --- a/drivers/lightnvm/pblk.h
> +++ b/drivers/lightnvm/pblk.h
> @@ -783,14 +783,10 @@ struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk,
> 					      struct ppa_addr ppa);
> void pblk_log_write_err(struct pblk *pblk, struct nvm_rq *rqd);
> void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd);
> -int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
> -int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd);
> -int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd);
> +int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
> +int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
> int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line);
> void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd);
> -struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
> -			      unsigned int nr_secs, unsigned int len,
> -			      int alloc_type, gfp_t gfp_mask);
> struct pblk_line *pblk_line_get(struct pblk *pblk);
> struct pblk_line *pblk_line_get_first_data(struct pblk *pblk);
> struct pblk_line *pblk_line_replace_data(struct pblk *pblk);
> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
> index d6f121452d5d..ec46693f6b64 100644
> --- a/drivers/nvme/host/lightnvm.c
> +++ b/drivers/nvme/host/lightnvm.c
> @@ -667,11 +667,14 @@ static struct request *nvme_nvm_alloc_request(struct request_queue *q,
> 	return rq;
> }
> 
> -static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
> +static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd,
> +			      void *buf)
> {
> +	struct nvm_geo *geo = &dev->geo;
> 	struct request_queue *q = dev->q;
> 	struct nvme_nvm_command *cmd;
> 	struct request *rq;
> +	int ret;
> 
> 	cmd = kzalloc(sizeof(struct nvme_nvm_command), GFP_KERNEL);
> 	if (!cmd)
> @@ -679,8 +682,15 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
> 
> 	rq = nvme_nvm_alloc_request(q, rqd, cmd);
> 	if (IS_ERR(rq)) {
> -		kfree(cmd);
> -		return PTR_ERR(rq);
> +		ret = PTR_ERR(rq);
> +		goto err_free_cmd;
> +	}
> +
> +	if (buf) {
> +		ret = blk_rq_map_kern(q, rq, buf, geo->csecs * rqd->nr_ppas,
> +				GFP_KERNEL);
> +		if (ret)
> +			goto err_free_cmd;
> 	}
> 
> 	rq->end_io_data = rqd;
> @@ -688,6 +698,10 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
> 	blk_execute_rq_nowait(q, NULL, rq, 0, nvme_nvm_end_io);
> 
> 	return 0;
> +
> +err_free_cmd:
> +	kfree(cmd);
> +	return ret;
> }
> 
> static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name,
> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
> index 8891647b24b1..ee8ec2e68055 100644
> --- a/include/linux/lightnvm.h
> +++ b/include/linux/lightnvm.h
> @@ -88,7 +88,7 @@ typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *);
> typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
> typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, sector_t, int,
> 							struct nvm_chk_meta *);
> -typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
> +typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *, void *);
> typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *, int);
> typedef void (nvm_destroy_dma_pool_fn)(void *);
> typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
> @@ -680,8 +680,8 @@ extern int nvm_get_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr,
> 			      int, struct nvm_chk_meta *);
> extern int nvm_set_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr *,
> 			      int, int);
> -extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *);
> -extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *);
> +extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *, void *);
> +extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *, void *);
> extern void nvm_end_io(struct nvm_rq *);
> 
> #else /* CONFIG_NVM */
> --
> 2.7.4

It’s very good to get rid of pblk_bio_map_addr(). Need to look at this
closer because I remember a number of corner cases due to the metadata
allocation. Have you tested the vmalloc allocation path? Note that you
need big lines for this to happen as it will try to do kmalloc if
possible.

Javier

[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata
  2019-07-31  9:41 ` [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata Hans Holmberg
@ 2019-07-31 14:00   ` Javier González
  2019-08-06  7:06   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Javier González @ 2019-07-31 14:00 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjørling, Christoph Hellwig, linux-block, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 7461 bytes --]

> On 31 Jul 2019, at 11.41, Hans Holmberg <hans@owltronix.com> wrote:
> 
> There is no reason now not to use kvmalloc, so
> so replace the internal metadata allocation scheme.

2 x so

> 
> Signed-off-by: Hans Holmberg <hans@owltronix.com>
> ---
> drivers/lightnvm/pblk-core.c |  3 +--
> drivers/lightnvm/pblk-gc.c   | 19 ++++++++-----------
> drivers/lightnvm/pblk-init.c | 38 ++++++++++----------------------------
> drivers/lightnvm/pblk.h      | 23 -----------------------
> 4 files changed, 19 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
> index a58d3c84a3f2..b413bafe93fd 100644
> --- a/drivers/lightnvm/pblk-core.c
> +++ b/drivers/lightnvm/pblk-core.c
> @@ -1839,8 +1839,7 @@ static void pblk_save_lba_list(struct pblk *pblk, struct pblk_line *line)
> 	struct pblk_w_err_gc *w_err_gc = line->w_err_gc;
> 	struct pblk_emeta *emeta = line->emeta;
> 
> -	w_err_gc->lba_list = pblk_malloc(lba_list_size,
> -					 l_mg->emeta_alloc_type, GFP_KERNEL);
> +	w_err_gc->lba_list = kvmalloc(lba_list_size, GFP_KERNEL);
> 	memcpy(w_err_gc->lba_list, emeta_to_lbas(pblk, emeta->buf),
> 				lba_list_size);
> }
> diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c
> index 63ee205b41c4..2581eebcfc41 100644
> --- a/drivers/lightnvm/pblk-gc.c
> +++ b/drivers/lightnvm/pblk-gc.c
> @@ -132,14 +132,12 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
> 				       struct pblk_line *line)
> {
> 	struct line_emeta *emeta_buf;
> -	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> 	struct pblk_line_meta *lm = &pblk->lm;
> 	unsigned int lba_list_size = lm->emeta_len[2];
> 	__le64 *lba_list;
> 	int ret;
> 
> -	emeta_buf = pblk_malloc(lm->emeta_len[0],
> -				l_mg->emeta_alloc_type, GFP_KERNEL);
> +	emeta_buf = kvmalloc(lm->emeta_len[0], GFP_KERNEL);
> 	if (!emeta_buf)
> 		return NULL;
> 
> @@ -147,7 +145,7 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
> 	if (ret) {
> 		pblk_err(pblk, "line %d read emeta failed (%d)\n",
> 				line->id, ret);
> -		pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
> +		kvfree(emeta_buf);
> 		return NULL;
> 	}
> 
> @@ -161,16 +159,16 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
> 	if (ret) {
> 		pblk_err(pblk, "inconsistent emeta (line %d)\n",
> 				line->id);
> -		pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
> +		kvfree(emeta_buf);
> 		return NULL;
> 	}
> 
> -	lba_list = pblk_malloc(lba_list_size,
> -			       l_mg->emeta_alloc_type, GFP_KERNEL);
> +	lba_list = kvmalloc(lba_list_size, GFP_KERNEL);
> +
> 	if (lba_list)
> 		memcpy(lba_list, emeta_to_lbas(pblk, emeta_buf), lba_list_size);
> 
> -	pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
> +	kvfree(emeta_buf);
> 
> 	return lba_list;
> }
> @@ -181,7 +179,6 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
> 									ws);
> 	struct pblk *pblk = line_ws->pblk;
> 	struct pblk_line *line = line_ws->line;
> -	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> 	struct pblk_line_meta *lm = &pblk->lm;
> 	struct nvm_tgt_dev *dev = pblk->dev;
> 	struct nvm_geo *geo = &dev->geo;
> @@ -272,7 +269,7 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
> 		goto next_rq;
> 
> out:
> -	pblk_mfree(lba_list, l_mg->emeta_alloc_type);
> +	kvfree(lba_list);
> 	kfree(line_ws);
> 	kfree(invalid_bitmap);
> 
> @@ -286,7 +283,7 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
> fail_free_gc_rq:
> 	kfree(gc_rq);
> fail_free_lba_list:
> -	pblk_mfree(lba_list, l_mg->emeta_alloc_type);
> +	kvfree(lba_list);
> fail_free_invalid_bitmap:
> 	kfree(invalid_bitmap);
> fail_free_ws:
> diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
> index b351c7f002de..9a967a2e83dd 100644
> --- a/drivers/lightnvm/pblk-init.c
> +++ b/drivers/lightnvm/pblk-init.c
> @@ -543,7 +543,7 @@ static void pblk_line_mg_free(struct pblk *pblk)
> 
> 	for (i = 0; i < PBLK_DATA_LINES; i++) {
> 		kfree(l_mg->sline_meta[i]);
> -		pblk_mfree(l_mg->eline_meta[i]->buf, l_mg->emeta_alloc_type);
> +		kvfree(l_mg->eline_meta[i]->buf);
> 		kfree(l_mg->eline_meta[i]);
> 	}
> 
> @@ -560,7 +560,7 @@ static void pblk_line_meta_free(struct pblk_line_mgmt *l_mg,
> 	kfree(line->erase_bitmap);
> 	kfree(line->chks);
> 
> -	pblk_mfree(w_err_gc->lba_list, l_mg->emeta_alloc_type);
> +	kvfree(w_err_gc->lba_list);
> 	kfree(w_err_gc);
> }
> 
> @@ -890,29 +890,14 @@ static int pblk_line_mg_init(struct pblk *pblk)
> 		if (!emeta)
> 			goto fail_free_emeta;
> 
> -		if (lm->emeta_len[0] > KMALLOC_MAX_CACHE_SIZE) {
> -			l_mg->emeta_alloc_type = PBLK_VMALLOC_META;
> -
> -			emeta->buf = vmalloc(lm->emeta_len[0]);
> -			if (!emeta->buf) {
> -				kfree(emeta);
> -				goto fail_free_emeta;
> -			}
> -
> -			emeta->nr_entries = lm->emeta_sec[0];
> -			l_mg->eline_meta[i] = emeta;
> -		} else {
> -			l_mg->emeta_alloc_type = PBLK_KMALLOC_META;
> -
> -			emeta->buf = kmalloc(lm->emeta_len[0], GFP_KERNEL);
> -			if (!emeta->buf) {
> -				kfree(emeta);
> -				goto fail_free_emeta;
> -			}
> -
> -			emeta->nr_entries = lm->emeta_sec[0];
> -			l_mg->eline_meta[i] = emeta;
> +		emeta->buf = kvmalloc(lm->emeta_len[0], GFP_KERNEL);
> +		if (!emeta->buf) {
> +			kfree(emeta);
> +			goto fail_free_emeta;
> 		}
> +
> +		emeta->nr_entries = lm->emeta_sec[0];
> +		l_mg->eline_meta[i] = emeta;
> 	}
> 
> 	for (i = 0; i < l_mg->nr_lines; i++)
> @@ -926,10 +911,7 @@ static int pblk_line_mg_init(struct pblk *pblk)
> 
> fail_free_emeta:
> 	while (--i >= 0) {
> -		if (l_mg->emeta_alloc_type == PBLK_VMALLOC_META)
> -			vfree(l_mg->eline_meta[i]->buf);
> -		else
> -			kfree(l_mg->eline_meta[i]->buf);
> +		kvfree(l_mg->eline_meta[i]->buf);
> 		kfree(l_mg->eline_meta[i]);
> 	}
> 
> diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
> index d515d3409a74..86ffa875bfe1 100644
> --- a/drivers/lightnvm/pblk.h
> +++ b/drivers/lightnvm/pblk.h
> @@ -482,11 +482,6 @@ struct pblk_line {
> #define PBLK_DATA_LINES 4
> 
> enum {
> -	PBLK_KMALLOC_META = 1,
> -	PBLK_VMALLOC_META = 2,
> -};
> -
> -enum {
> 	PBLK_EMETA_TYPE_HEADER = 1,	/* struct line_emeta first sector */
> 	PBLK_EMETA_TYPE_LLBA = 2,	/* lba list - type: __le64 */
> 	PBLK_EMETA_TYPE_VSC = 3,	/* vsc list - type: __le32 */
> @@ -521,9 +516,6 @@ struct pblk_line_mgmt {
> 
> 	__le32 *vsc_list;		/* Valid sector counts for all lines */
> 
> -	/* Metadata allocation type: VMALLOC | KMALLOC */
> -	int emeta_alloc_type;
> -
> 	/* Pre-allocated metadata for data lines */
> 	struct pblk_smeta *sline_meta[PBLK_DATA_LINES];
> 	struct pblk_emeta *eline_meta[PBLK_DATA_LINES];
> @@ -934,21 +926,6 @@ void pblk_rl_werr_line_out(struct pblk_rl *rl);
> int pblk_sysfs_init(struct gendisk *tdisk);
> void pblk_sysfs_exit(struct gendisk *tdisk);
> 
> -static inline void *pblk_malloc(size_t size, int type, gfp_t flags)
> -{
> -	if (type == PBLK_KMALLOC_META)
> -		return kmalloc(size, flags);
> -	return vmalloc(size);
> -}
> -
> -static inline void pblk_mfree(void *ptr, int type)
> -{
> -	if (type == PBLK_KMALLOC_META)
> -		kfree(ptr);
> -	else
> -		vfree(ptr);
> -}
> -
> static inline struct nvm_rq *nvm_rq_from_c_ctx(void *c_ctx)
> {
> 	return c_ctx - sizeof(struct nvm_rq);
> --
> 2.7.4

Looks good to me.

Reviewed-by: Javier González <javier@javigon.com>




[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/4] block: stop exporting bio_map_kern
  2019-07-31  9:41 ` [PATCH 4/4] block: stop exporting bio_map_kern Hans Holmberg
@ 2019-07-31 17:13   ` Javier González
  2019-08-06  7:07   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Javier González @ 2019-07-31 17:13 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjørling, Christoph Hellwig, linux-block, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 816 bytes --]

> On 31 Jul 2019, at 11.41, Hans Holmberg <hans@owltronix.com> wrote:
> 
> Now that there no module users left of bio_map_kern, stop
> exporting the symbol.
> 
> Signed-off-by: Hans Holmberg <hans@owltronix.com>
> ---
> block/bio.c | 1 -
> 1 file changed, 1 deletion(-)
> 
> diff --git a/block/bio.c b/block/bio.c
> index 299a0e7651ec..96ca0b4e73bb 100644
> --- a/block/bio.c
> +++ b/block/bio.c
> @@ -1521,7 +1521,6 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
> 	bio->bi_end_io = bio_map_kern_endio;
> 	return bio;
> }
> -EXPORT_SYMBOL(bio_map_kern);
> 
> static void bio_copy_kern_endio(struct bio *bio)
> {
> --
> 2.7.4

Haven’t realized we were the only users at this point. Nice cleanup.

Reviewed-by: Javier González <javier@javigon.com>


[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/4] lightnvm: move metadata mapping to lower level driver
  2019-07-31 13:58   ` Javier González
@ 2019-08-01  7:15     ` Hans Holmberg
  2019-08-01  7:46       ` Javier González
  0 siblings, 1 reply; 17+ messages in thread
From: Hans Holmberg @ 2019-08-01  7:15 UTC (permalink / raw)
  To: Javier González
  Cc: Matias Bjørling, Christoph Hellwig, linux-block,
	Linux Kernel Mailing List

On Wed, Jul 31, 2019 at 3:59 PM Javier González <javier@javigon.com> wrote:
>
> > On 31 Jul 2019, at 11.41, Hans Holmberg <hans@owltronix.com> wrote:
> >
> > Now that blk_rq_map_kern can map both kmem and vmem, move
> > internal metadata mapping down to the lower level driver.
> >
> > Signed-off-by: Hans Holmberg <hans@owltronix.com>
> > ---
> > drivers/lightnvm/core.c          |  16 +++---
> > drivers/lightnvm/pblk-core.c     | 113 +++++----------------------------------
> > drivers/lightnvm/pblk-read.c     |  22 ++------
> > drivers/lightnvm/pblk-recovery.c |  39 ++------------
> > drivers/lightnvm/pblk-write.c    |  20 ++-----
> > drivers/lightnvm/pblk.h          |   8 +--
> > drivers/nvme/host/lightnvm.c     |  20 +++++--
> > include/linux/lightnvm.h         |   6 +--
> > 8 files changed, 54 insertions(+), 190 deletions(-)
> >
> > diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
> > index 01d098fb96ac..3cd03582a2ed 100644
> > --- a/drivers/lightnvm/core.c
> > +++ b/drivers/lightnvm/core.c
> > @@ -731,7 +731,7 @@ static int nvm_set_flags(struct nvm_geo *geo, struct nvm_rq *rqd)
> >       return flags;
> > }
> >
> > -int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> > +int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd, void *buf)
> > {
> >       struct nvm_dev *dev = tgt_dev->parent;
> >       int ret;
> > @@ -745,7 +745,7 @@ int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> >       rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
> >
> >       /* In case of error, fail with right address format */
> > -     ret = dev->ops->submit_io(dev, rqd);
> > +     ret = dev->ops->submit_io(dev, rqd, buf);
> >       if (ret)
> >               nvm_rq_dev_to_tgt(tgt_dev, rqd);
> >       return ret;
> > @@ -759,7 +759,8 @@ static void nvm_sync_end_io(struct nvm_rq *rqd)
> >       complete(waiting);
> > }
> >
> > -static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
> > +static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd,
> > +                           void *buf)
> > {
> >       DECLARE_COMPLETION_ONSTACK(wait);
> >       int ret = 0;
> > @@ -767,7 +768,7 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
> >       rqd->end_io = nvm_sync_end_io;
> >       rqd->private = &wait;
> >
> > -     ret = dev->ops->submit_io(dev, rqd);
> > +     ret = dev->ops->submit_io(dev, rqd, buf);
> >       if (ret)
> >               return ret;
> >
> > @@ -776,7 +777,8 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
> >       return 0;
> > }
> >
> > -int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> > +int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd,
> > +                    void *buf)
> > {
> >       struct nvm_dev *dev = tgt_dev->parent;
> >       int ret;
> > @@ -789,7 +791,7 @@ int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
> >       rqd->dev = tgt_dev;
> >       rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
> >
> > -     ret = nvm_submit_io_wait(dev, rqd);
> > +     ret = nvm_submit_io_wait(dev, rqd, buf);
> >
> >       return ret;
> > }
> > @@ -816,7 +818,7 @@ static int nvm_submit_io_sync_raw(struct nvm_dev *dev, struct nvm_rq *rqd)
> >       rqd->dev = NULL;
> >       rqd->flags = nvm_set_flags(&dev->geo, rqd);
> >
> > -     return nvm_submit_io_wait(dev, rqd);
> > +     return nvm_submit_io_wait(dev, rqd, NULL);
> > }
> >
> > static int nvm_bb_chunk_sense(struct nvm_dev *dev, struct ppa_addr ppa)
> > diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
> > index f546e6f28b8a..a58d3c84a3f2 100644
> > --- a/drivers/lightnvm/pblk-core.c
> > +++ b/drivers/lightnvm/pblk-core.c
> > @@ -507,7 +507,7 @@ void pblk_set_sec_per_write(struct pblk *pblk, int sec_per_write)
> >       pblk->sec_per_write = sec_per_write;
> > }
> >
> > -int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
> > +int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
> > {
> >       struct nvm_tgt_dev *dev = pblk->dev;
> >
> > @@ -518,7 +518,7 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
> >               return NVM_IO_ERR;
> > #endif
> >
> > -     return nvm_submit_io(dev, rqd);
> > +     return nvm_submit_io(dev, rqd, buf);
> > }
> >
> > void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
> > @@ -541,7 +541,7 @@ void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
> >       }
> > }
> >
> > -int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
> > +int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
> > {
> >       struct nvm_tgt_dev *dev = pblk->dev;
> >       int ret;
> > @@ -553,7 +553,7 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
> >               return NVM_IO_ERR;
> > #endif
> >
> > -     ret = nvm_submit_io_sync(dev, rqd);
> > +     ret = nvm_submit_io_sync(dev, rqd, buf);
> >
> >       if (trace_pblk_chunk_state_enabled() && !ret &&
> >           rqd->opcode == NVM_OP_PWRITE)
> > @@ -562,65 +562,19 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
> >       return ret;
> > }
> >
> > -int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd)
> > +static int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd,
> > +                                void *buf)
> > {
> >       struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
> >       int ret;
> >
> >       pblk_down_chunk(pblk, ppa_list[0]);
> > -     ret = pblk_submit_io_sync(pblk, rqd);
> > +     ret = pblk_submit_io_sync(pblk, rqd, buf);
> >       pblk_up_chunk(pblk, ppa_list[0]);
> >
> >       return ret;
> > }
> >
> > -static void pblk_bio_map_addr_endio(struct bio *bio)
> > -{
> > -     bio_put(bio);
> > -}
> > -
> > -struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
> > -                           unsigned int nr_secs, unsigned int len,
> > -                           int alloc_type, gfp_t gfp_mask)
> > -{
> > -     struct nvm_tgt_dev *dev = pblk->dev;
> > -     void *kaddr = data;
> > -     struct page *page;
> > -     struct bio *bio;
> > -     int i, ret;
> > -
> > -     if (alloc_type == PBLK_KMALLOC_META)
> > -             return bio_map_kern(dev->q, kaddr, len, gfp_mask);
> > -
> > -     bio = bio_kmalloc(gfp_mask, nr_secs);
> > -     if (!bio)
> > -             return ERR_PTR(-ENOMEM);
> > -
> > -     for (i = 0; i < nr_secs; i++) {
> > -             page = vmalloc_to_page(kaddr);
> > -             if (!page) {
> > -                     pblk_err(pblk, "could not map vmalloc bio\n");
> > -                     bio_put(bio);
> > -                     bio = ERR_PTR(-ENOMEM);
> > -                     goto out;
> > -             }
> > -
> > -             ret = bio_add_pc_page(dev->q, bio, page, PAGE_SIZE, 0);
> > -             if (ret != PAGE_SIZE) {
> > -                     pblk_err(pblk, "could not add page to bio\n");
> > -                     bio_put(bio);
> > -                     bio = ERR_PTR(-ENOMEM);
> > -                     goto out;
> > -             }
> > -
> > -             kaddr += PAGE_SIZE;
> > -     }
> > -
> > -     bio->bi_end_io = pblk_bio_map_addr_endio;
> > -out:
> > -     return bio;
> > -}
> > -
> > int pblk_calc_secs(struct pblk *pblk, unsigned long secs_avail,
> >                  unsigned long secs_to_flush, bool skip_meta)
> > {
> > @@ -722,9 +676,7 @@ u64 pblk_line_smeta_start(struct pblk *pblk, struct pblk_line *line)
> >
> > int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> > {
> > -     struct nvm_tgt_dev *dev = pblk->dev;
> >       struct pblk_line_meta *lm = &pblk->lm;
> > -     struct bio *bio;
> >       struct ppa_addr *ppa_list;
> >       struct nvm_rq rqd;
> >       u64 paddr = pblk_line_smeta_start(pblk, line);
> > @@ -736,16 +688,6 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> >       if (ret)
> >               return ret;
> >
> > -     bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
> > -     if (IS_ERR(bio)) {
> > -             ret = PTR_ERR(bio);
> > -             goto clear_rqd;
> > -     }
> > -
> > -     bio->bi_iter.bi_sector = 0; /* internal bio */
> > -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
> > -
> > -     rqd.bio = bio;
> >       rqd.opcode = NVM_OP_PREAD;
> >       rqd.nr_ppas = lm->smeta_sec;
> >       rqd.is_seq = 1;
> > @@ -754,10 +696,9 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> >       for (i = 0; i < lm->smeta_sec; i++, paddr++)
> >               ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line->id);
> >
> > -     ret = pblk_submit_io_sync(pblk, &rqd);
> > +     ret = pblk_submit_io_sync(pblk, &rqd, line->smeta);
> >       if (ret) {
> >               pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
> > -             bio_put(bio);
> >               goto clear_rqd;
> >       }
> >
> > @@ -776,9 +717,7 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
> > static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
> >                                u64 paddr)
> > {
> > -     struct nvm_tgt_dev *dev = pblk->dev;
> >       struct pblk_line_meta *lm = &pblk->lm;
> > -     struct bio *bio;
> >       struct ppa_addr *ppa_list;
> >       struct nvm_rq rqd;
> >       __le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
> > @@ -791,16 +730,6 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
> >       if (ret)
> >               return ret;
> >
> > -     bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
> > -     if (IS_ERR(bio)) {
> > -             ret = PTR_ERR(bio);
> > -             goto clear_rqd;
> > -     }
> > -
> > -     bio->bi_iter.bi_sector = 0; /* internal bio */
> > -     bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
> > -
> > -     rqd.bio = bio;
> >       rqd.opcode = NVM_OP_PWRITE;
> >       rqd.nr_ppas = lm->smeta_sec;
> >       rqd.is_seq = 1;
> > @@ -814,10 +743,9 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
> >               meta->lba = lba_list[paddr] = addr_empty;
> >       }
> >
> > -     ret = pblk_submit_io_sync_sem(pblk, &rqd);
> > +     ret = pblk_submit_io_sync_sem(pblk, &rqd, line->smeta);
> >       if (ret) {
> >               pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
> > -             bio_put(bio);
> >               goto clear_rqd;
> >       }
> >
> > @@ -838,10 +766,8 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> > {
> >       struct nvm_tgt_dev *dev = pblk->dev;
> >       struct nvm_geo *geo = &dev->geo;
> > -     struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> >       struct pblk_line_meta *lm = &pblk->lm;
> >       void *ppa_list_buf, *meta_list;
> > -     struct bio *bio;
> >       struct ppa_addr *ppa_list;
> >       struct nvm_rq rqd;
> >       u64 paddr = line->emeta_ssec;
> > @@ -867,17 +793,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> >       rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
> >       rq_len = rq_ppas * geo->csecs;
> >
> > -     bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len,
> > -                                     l_mg->emeta_alloc_type, GFP_KERNEL);
> > -     if (IS_ERR(bio)) {
> > -             ret = PTR_ERR(bio);
> > -             goto free_rqd_dma;
> > -     }
> > -
> > -     bio->bi_iter.bi_sector = 0; /* internal bio */
> > -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
> > -
> > -     rqd.bio = bio;
> >       rqd.meta_list = meta_list;
> >       rqd.ppa_list = ppa_list_buf;
> >       rqd.dma_meta_list = dma_meta_list;
> > @@ -896,7 +811,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> >               while (test_bit(pos, line->blk_bitmap)) {
> >                       paddr += min;
> >                       if (pblk_boundary_paddr_checks(pblk, paddr)) {
> > -                             bio_put(bio);
> >                               ret = -EINTR;
> >                               goto free_rqd_dma;
> >                       }
> > @@ -906,7 +820,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> >               }
> >
> >               if (pblk_boundary_paddr_checks(pblk, paddr + min)) {
> > -                     bio_put(bio);
> >                       ret = -EINTR;
> >                       goto free_rqd_dma;
> >               }
> > @@ -915,10 +828,9 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> >                       ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line_id);
> >       }
> >
> > -     ret = pblk_submit_io_sync(pblk, &rqd);
> > +     ret = pblk_submit_io_sync(pblk, &rqd, emeta_buf);
> >       if (ret) {
> >               pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
> > -             bio_put(bio);
> >               goto free_rqd_dma;
> >       }
> >
> > @@ -963,7 +875,7 @@ static int pblk_blk_erase_sync(struct pblk *pblk, struct ppa_addr ppa)
> >       /* The write thread schedules erases so that it minimizes disturbances
> >        * with writes. Thus, there is no need to take the LUN semaphore.
> >        */
> > -     ret = pblk_submit_io_sync(pblk, &rqd);
> > +     ret = pblk_submit_io_sync(pblk, &rqd, NULL);
> >       rqd.private = pblk;
> >       __pblk_end_io_erase(pblk, &rqd);
> >
> > @@ -1792,7 +1704,7 @@ int pblk_blk_erase_async(struct pblk *pblk, struct ppa_addr ppa)
> >       /* The write thread schedules erases so that it minimizes disturbances
> >        * with writes. Thus, there is no need to take the LUN semaphore.
> >        */
> > -     err = pblk_submit_io(pblk, rqd);
> > +     err = pblk_submit_io(pblk, rqd, NULL);
> >       if (err) {
> >               struct nvm_tgt_dev *dev = pblk->dev;
> >               struct nvm_geo *geo = &dev->geo;
> > @@ -1923,7 +1835,6 @@ void pblk_line_close_meta(struct pblk *pblk, struct pblk_line *line)
> > static void pblk_save_lba_list(struct pblk *pblk, struct pblk_line *line)
> > {
> >       struct pblk_line_meta *lm = &pblk->lm;
> > -     struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> >       unsigned int lba_list_size = lm->emeta_len[2];
> >       struct pblk_w_err_gc *w_err_gc = line->w_err_gc;
> >       struct pblk_emeta *emeta = line->emeta;
> > diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c
> > index d98ea392fe33..d572d4559e4e 100644
> > --- a/drivers/lightnvm/pblk-read.c
> > +++ b/drivers/lightnvm/pblk-read.c
> > @@ -342,7 +342,7 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio)
> >               bio_put(int_bio);
> >               int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set);
> >               goto split_retry;
> > -     } else if (pblk_submit_io(pblk, rqd)) {
> > +     } else if (pblk_submit_io(pblk, rqd, NULL)) {
> >               /* Submitting IO to drive failed, let's report an error */
> >               rqd->error = -ENODEV;
> >               pblk_end_io_read(rqd);
> > @@ -419,7 +419,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
> > {
> >       struct nvm_tgt_dev *dev = pblk->dev;
> >       struct nvm_geo *geo = &dev->geo;
> > -     struct bio *bio;
> >       struct nvm_rq rqd;
> >       int data_len;
> >       int ret = NVM_IO_OK;
> > @@ -447,25 +446,12 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
> >               goto out;
> >
> >       data_len = (gc_rq->secs_to_gc) * geo->csecs;
> > -     bio = pblk_bio_map_addr(pblk, gc_rq->data, gc_rq->secs_to_gc, data_len,
> > -                                             PBLK_VMALLOC_META, GFP_KERNEL);
> > -     if (IS_ERR(bio)) {
> > -             pblk_err(pblk, "could not allocate GC bio (%lu)\n",
> > -                                                             PTR_ERR(bio));
> > -             ret = PTR_ERR(bio);
> > -             goto err_free_dma;
> > -     }
> > -
> > -     bio->bi_iter.bi_sector = 0; /* internal bio */
> > -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
> > -
> >       rqd.opcode = NVM_OP_PREAD;
> >       rqd.nr_ppas = gc_rq->secs_to_gc;
> > -     rqd.bio = bio;
> >
> > -     if (pblk_submit_io_sync(pblk, &rqd)) {
> > +     if (pblk_submit_io_sync(pblk, &rqd, gc_rq->data)) {
> >               ret = -EIO;
> > -             goto err_free_bio;
> > +             goto err_free_dma;
> >       }
> >
> >       pblk_read_check_rand(pblk, &rqd, gc_rq->lba_list, gc_rq->nr_secs);
> > @@ -489,8 +475,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
> >       pblk_free_rqd_meta(pblk, &rqd);
> >       return ret;
> >
> > -err_free_bio:
> > -     bio_put(bio);
> > err_free_dma:
> >       pblk_free_rqd_meta(pblk, &rqd);
> >       return ret;
> > diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
> > index e6dda04de144..d5e210c3c5b7 100644
> > --- a/drivers/lightnvm/pblk-recovery.c
> > +++ b/drivers/lightnvm/pblk-recovery.c
> > @@ -178,12 +178,11 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
> >       void *meta_list;
> >       struct pblk_pad_rq *pad_rq;
> >       struct nvm_rq *rqd;
> > -     struct bio *bio;
> >       struct ppa_addr *ppa_list;
> >       void *data;
> >       __le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
> >       u64 w_ptr = line->cur_sec;
> > -     int left_line_ppas, rq_ppas, rq_len;
> > +     int left_line_ppas, rq_ppas;
> >       int i, j;
> >       int ret = 0;
> >
> > @@ -212,28 +211,15 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
> >               goto fail_complete;
> >       }
> >
> > -     rq_len = rq_ppas * geo->csecs;
> > -
> > -     bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
> > -                                             PBLK_VMALLOC_META, GFP_KERNEL);
> > -     if (IS_ERR(bio)) {
> > -             ret = PTR_ERR(bio);
> > -             goto fail_complete;
> > -     }
> > -
> > -     bio->bi_iter.bi_sector = 0; /* internal bio */
> > -     bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
> > -
> >       rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT);
> >
> >       ret = pblk_alloc_rqd_meta(pblk, rqd);
> >       if (ret) {
> >               pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
> > -             bio_put(bio);
> >               goto fail_complete;
> >       }
> >
> > -     rqd->bio = bio;
> > +     rqd->bio = NULL;
> >       rqd->opcode = NVM_OP_PWRITE;
> >       rqd->is_seq = 1;
> >       rqd->nr_ppas = rq_ppas;
> > @@ -275,13 +261,12 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
> >       kref_get(&pad_rq->ref);
> >       pblk_down_chunk(pblk, ppa_list[0]);
> >
> > -     ret = pblk_submit_io(pblk, rqd);
> > +     ret = pblk_submit_io(pblk, rqd, data);
> >       if (ret) {
> >               pblk_err(pblk, "I/O submission failed: %d\n", ret);
> >               pblk_up_chunk(pblk, ppa_list[0]);
> >               kref_put(&pad_rq->ref, pblk_recov_complete);
> >               pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
> > -             bio_put(bio);
> >               goto fail_complete;
> >       }
> >
> > @@ -375,7 +360,6 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> >       struct ppa_addr *ppa_list;
> >       void *meta_list;
> >       struct nvm_rq *rqd;
> > -     struct bio *bio;
> >       void *data;
> >       dma_addr_t dma_ppa_list, dma_meta_list;
> >       __le64 *lba_list;
> > @@ -407,15 +391,7 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> >       rq_len = rq_ppas * geo->csecs;
> >
> > retry_rq:
> > -     bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL);
> > -     if (IS_ERR(bio))
> > -             return PTR_ERR(bio);
> > -
> > -     bio->bi_iter.bi_sector = 0; /* internal bio */
> > -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
> > -     bio_get(bio);
> > -
> > -     rqd->bio = bio;
> > +     rqd->bio = NULL;
> >       rqd->opcode = NVM_OP_PREAD;
> >       rqd->meta_list = meta_list;
> >       rqd->nr_ppas = rq_ppas;
> > @@ -445,10 +421,9 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> >                               addr_to_gen_ppa(pblk, paddr + j, line->id);
> >       }
> >
> > -     ret = pblk_submit_io_sync(pblk, rqd);
> > +     ret = pblk_submit_io_sync(pblk, rqd, data);
> >       if (ret) {
> >               pblk_err(pblk, "I/O submission failed: %d\n", ret);
> > -             bio_put(bio);
> >               return ret;
> >       }
> >
> > @@ -460,24 +435,20 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
> >
> >               if (padded) {
> >                       pblk_log_read_err(pblk, rqd);
> > -                     bio_put(bio);
> >                       return -EINTR;
> >               }
> >
> >               pad_distance = pblk_pad_distance(pblk, line);
> >               ret = pblk_recov_pad_line(pblk, line, pad_distance);
> >               if (ret) {
> > -                     bio_put(bio);
> >                       return ret;
> >               }
> >
> >               padded = true;
> > -             bio_put(bio);
> >               goto retry_rq;
> >       }
> >
> >       pblk_get_packed_meta(pblk, rqd);
> > -     bio_put(bio);
> >
> >       for (i = 0; i < rqd->nr_ppas; i++) {
> >               struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i);
> > diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
> > index 4e63f9b5954c..b9a2aeba95ab 100644
> > --- a/drivers/lightnvm/pblk-write.c
> > +++ b/drivers/lightnvm/pblk-write.c
> > @@ -373,7 +373,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> >       struct pblk_emeta *emeta = meta_line->emeta;
> >       struct ppa_addr *ppa_list;
> >       struct pblk_g_ctx *m_ctx;
> > -     struct bio *bio;
> >       struct nvm_rq *rqd;
> >       void *data;
> >       u64 paddr;
> > @@ -391,20 +390,9 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> >       rq_len = rq_ppas * geo->csecs;
> >       data = ((void *)emeta->buf) + emeta->mem;
> >
> > -     bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
> > -                                     l_mg->emeta_alloc_type, GFP_KERNEL);
> > -     if (IS_ERR(bio)) {
> > -             pblk_err(pblk, "failed to map emeta io");
> > -             ret = PTR_ERR(bio);
> > -             goto fail_free_rqd;
> > -     }
> > -     bio->bi_iter.bi_sector = 0; /* internal bio */
> > -     bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
> > -     rqd->bio = bio;
> > -
> >       ret = pblk_alloc_w_rq(pblk, rqd, rq_ppas, pblk_end_io_write_meta);
> >       if (ret)
> > -             goto fail_free_bio;
> > +             goto fail_free_rqd;
> >
> >       ppa_list = nvm_rq_to_ppa_list(rqd);
> >       for (i = 0; i < rqd->nr_ppas; ) {
> > @@ -423,7 +411,7 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> >
> >       pblk_down_chunk(pblk, ppa_list[0]);
> >
> > -     ret = pblk_submit_io(pblk, rqd);
> > +     ret = pblk_submit_io(pblk, rqd, data);
> >       if (ret) {
> >               pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
> >               goto fail_rollback;
> > @@ -437,8 +425,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
> >       pblk_dealloc_page(pblk, meta_line, rq_ppas);
> >       list_add(&meta_line->list, &meta_line->list);
> >       spin_unlock(&l_mg->close_lock);
> > -fail_free_bio:
> > -     bio_put(bio);
> > fail_free_rqd:
> >       pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
> >       return ret;
> > @@ -523,7 +509,7 @@ static int pblk_submit_io_set(struct pblk *pblk, struct nvm_rq *rqd)
> >       meta_line = pblk_should_submit_meta_io(pblk, rqd);
> >
> >       /* Submit data write for current data line */
> > -     err = pblk_submit_io(pblk, rqd);
> > +     err = pblk_submit_io(pblk, rqd, NULL);
> >       if (err) {
> >               pblk_err(pblk, "data I/O submission failed: %d\n", err);
> >               return NVM_IO_ERR;
> > diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
> > index a67855387f53..d515d3409a74 100644
> > --- a/drivers/lightnvm/pblk.h
> > +++ b/drivers/lightnvm/pblk.h
> > @@ -783,14 +783,10 @@ struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk,
> >                                             struct ppa_addr ppa);
> > void pblk_log_write_err(struct pblk *pblk, struct nvm_rq *rqd);
> > void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd);
> > -int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
> > -int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd);
> > -int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd);
> > +int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
> > +int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
> > int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line);
> > void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd);
> > -struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
> > -                           unsigned int nr_secs, unsigned int len,
> > -                           int alloc_type, gfp_t gfp_mask);
> > struct pblk_line *pblk_line_get(struct pblk *pblk);
> > struct pblk_line *pblk_line_get_first_data(struct pblk *pblk);
> > struct pblk_line *pblk_line_replace_data(struct pblk *pblk);
> > diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
> > index d6f121452d5d..ec46693f6b64 100644
> > --- a/drivers/nvme/host/lightnvm.c
> > +++ b/drivers/nvme/host/lightnvm.c
> > @@ -667,11 +667,14 @@ static struct request *nvme_nvm_alloc_request(struct request_queue *q,
> >       return rq;
> > }
> >
> > -static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
> > +static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd,
> > +                           void *buf)
> > {
> > +     struct nvm_geo *geo = &dev->geo;
> >       struct request_queue *q = dev->q;
> >       struct nvme_nvm_command *cmd;
> >       struct request *rq;
> > +     int ret;
> >
> >       cmd = kzalloc(sizeof(struct nvme_nvm_command), GFP_KERNEL);
> >       if (!cmd)
> > @@ -679,8 +682,15 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
> >
> >       rq = nvme_nvm_alloc_request(q, rqd, cmd);
> >       if (IS_ERR(rq)) {
> > -             kfree(cmd);
> > -             return PTR_ERR(rq);
> > +             ret = PTR_ERR(rq);
> > +             goto err_free_cmd;
> > +     }
> > +
> > +     if (buf) {
> > +             ret = blk_rq_map_kern(q, rq, buf, geo->csecs * rqd->nr_ppas,
> > +                             GFP_KERNEL);
> > +             if (ret)
> > +                     goto err_free_cmd;
> >       }
> >
> >       rq->end_io_data = rqd;
> > @@ -688,6 +698,10 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
> >       blk_execute_rq_nowait(q, NULL, rq, 0, nvme_nvm_end_io);
> >
> >       return 0;
> > +
> > +err_free_cmd:
> > +     kfree(cmd);
> > +     return ret;
> > }
> >
> > static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name,
> > diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
> > index 8891647b24b1..ee8ec2e68055 100644
> > --- a/include/linux/lightnvm.h
> > +++ b/include/linux/lightnvm.h
> > @@ -88,7 +88,7 @@ typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *);
> > typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
> > typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, sector_t, int,
> >                                                       struct nvm_chk_meta *);
> > -typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
> > +typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *, void *);
> > typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *, int);
> > typedef void (nvm_destroy_dma_pool_fn)(void *);
> > typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
> > @@ -680,8 +680,8 @@ extern int nvm_get_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr,
> >                             int, struct nvm_chk_meta *);
> > extern int nvm_set_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr *,
> >                             int, int);
> > -extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *);
> > -extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *);
> > +extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *, void *);
> > +extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *, void *);
> > extern void nvm_end_io(struct nvm_rq *);
> >
> > #else /* CONFIG_NVM */
> > --
> > 2.7.4
>
> It’s very good to get rid of pblk_bio_map_addr(). Need to look at this
> closer because I remember a number of corner cases due to the metadata
> allocation. Have you tested the vmalloc allocation path? Note that you
> need big lines for this to happen as it will try to do kmalloc if
> possible

Yeah, i checked that vmalloc worked for the emeta buffers(by switching
over manually), so we should be good.

>
> Javier

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/4] lightnvm: move metadata mapping to lower level driver
  2019-08-01  7:15     ` Hans Holmberg
@ 2019-08-01  7:46       ` Javier González
  0 siblings, 0 replies; 17+ messages in thread
From: Javier González @ 2019-08-01  7:46 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjørling, Christoph Hellwig, linux-block,
	Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 29806 bytes --]

> On 1 Aug 2019, at 09.15, Hans Holmberg <hans@owltronix.com> wrote:
> 
> On Wed, Jul 31, 2019 at 3:59 PM Javier González <javier@javigon.com> wrote:
>>> On 31 Jul 2019, at 11.41, Hans Holmberg <hans@owltronix.com> wrote:
>>> 
>>> Now that blk_rq_map_kern can map both kmem and vmem, move
>>> internal metadata mapping down to the lower level driver.
>>> 
>>> Signed-off-by: Hans Holmberg <hans@owltronix.com>
>>> ---
>>> drivers/lightnvm/core.c          |  16 +++---
>>> drivers/lightnvm/pblk-core.c     | 113 +++++----------------------------------
>>> drivers/lightnvm/pblk-read.c     |  22 ++------
>>> drivers/lightnvm/pblk-recovery.c |  39 ++------------
>>> drivers/lightnvm/pblk-write.c    |  20 ++-----
>>> drivers/lightnvm/pblk.h          |   8 +--
>>> drivers/nvme/host/lightnvm.c     |  20 +++++--
>>> include/linux/lightnvm.h         |   6 +--
>>> 8 files changed, 54 insertions(+), 190 deletions(-)
>>> 
>>> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
>>> index 01d098fb96ac..3cd03582a2ed 100644
>>> --- a/drivers/lightnvm/core.c
>>> +++ b/drivers/lightnvm/core.c
>>> @@ -731,7 +731,7 @@ static int nvm_set_flags(struct nvm_geo *geo, struct nvm_rq *rqd)
>>>      return flags;
>>> }
>>> 
>>> -int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
>>> +int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd, void *buf)
>>> {
>>>      struct nvm_dev *dev = tgt_dev->parent;
>>>      int ret;
>>> @@ -745,7 +745,7 @@ int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
>>>      rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
>>> 
>>>      /* In case of error, fail with right address format */
>>> -     ret = dev->ops->submit_io(dev, rqd);
>>> +     ret = dev->ops->submit_io(dev, rqd, buf);
>>>      if (ret)
>>>              nvm_rq_dev_to_tgt(tgt_dev, rqd);
>>>      return ret;
>>> @@ -759,7 +759,8 @@ static void nvm_sync_end_io(struct nvm_rq *rqd)
>>>      complete(waiting);
>>> }
>>> 
>>> -static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
>>> +static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd,
>>> +                           void *buf)
>>> {
>>>      DECLARE_COMPLETION_ONSTACK(wait);
>>>      int ret = 0;
>>> @@ -767,7 +768,7 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
>>>      rqd->end_io = nvm_sync_end_io;
>>>      rqd->private = &wait;
>>> 
>>> -     ret = dev->ops->submit_io(dev, rqd);
>>> +     ret = dev->ops->submit_io(dev, rqd, buf);
>>>      if (ret)
>>>              return ret;
>>> 
>>> @@ -776,7 +777,8 @@ static int nvm_submit_io_wait(struct nvm_dev *dev, struct nvm_rq *rqd)
>>>      return 0;
>>> }
>>> 
>>> -int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
>>> +int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd,
>>> +                    void *buf)
>>> {
>>>      struct nvm_dev *dev = tgt_dev->parent;
>>>      int ret;
>>> @@ -789,7 +791,7 @@ int nvm_submit_io_sync(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
>>>      rqd->dev = tgt_dev;
>>>      rqd->flags = nvm_set_flags(&tgt_dev->geo, rqd);
>>> 
>>> -     ret = nvm_submit_io_wait(dev, rqd);
>>> +     ret = nvm_submit_io_wait(dev, rqd, buf);
>>> 
>>>      return ret;
>>> }
>>> @@ -816,7 +818,7 @@ static int nvm_submit_io_sync_raw(struct nvm_dev *dev, struct nvm_rq *rqd)
>>>      rqd->dev = NULL;
>>>      rqd->flags = nvm_set_flags(&dev->geo, rqd);
>>> 
>>> -     return nvm_submit_io_wait(dev, rqd);
>>> +     return nvm_submit_io_wait(dev, rqd, NULL);
>>> }
>>> 
>>> static int nvm_bb_chunk_sense(struct nvm_dev *dev, struct ppa_addr ppa)
>>> diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
>>> index f546e6f28b8a..a58d3c84a3f2 100644
>>> --- a/drivers/lightnvm/pblk-core.c
>>> +++ b/drivers/lightnvm/pblk-core.c
>>> @@ -507,7 +507,7 @@ void pblk_set_sec_per_write(struct pblk *pblk, int sec_per_write)
>>>      pblk->sec_per_write = sec_per_write;
>>> }
>>> 
>>> -int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
>>> +int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
>>> {
>>>      struct nvm_tgt_dev *dev = pblk->dev;
>>> 
>>> @@ -518,7 +518,7 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
>>>              return NVM_IO_ERR;
>>> #endif
>>> 
>>> -     return nvm_submit_io(dev, rqd);
>>> +     return nvm_submit_io(dev, rqd, buf);
>>> }
>>> 
>>> void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
>>> @@ -541,7 +541,7 @@ void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
>>>      }
>>> }
>>> 
>>> -int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
>>> +int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf)
>>> {
>>>      struct nvm_tgt_dev *dev = pblk->dev;
>>>      int ret;
>>> @@ -553,7 +553,7 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
>>>              return NVM_IO_ERR;
>>> #endif
>>> 
>>> -     ret = nvm_submit_io_sync(dev, rqd);
>>> +     ret = nvm_submit_io_sync(dev, rqd, buf);
>>> 
>>>      if (trace_pblk_chunk_state_enabled() && !ret &&
>>>          rqd->opcode == NVM_OP_PWRITE)
>>> @@ -562,65 +562,19 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
>>>      return ret;
>>> }
>>> 
>>> -int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd)
>>> +static int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd,
>>> +                                void *buf)
>>> {
>>>      struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
>>>      int ret;
>>> 
>>>      pblk_down_chunk(pblk, ppa_list[0]);
>>> -     ret = pblk_submit_io_sync(pblk, rqd);
>>> +     ret = pblk_submit_io_sync(pblk, rqd, buf);
>>>      pblk_up_chunk(pblk, ppa_list[0]);
>>> 
>>>      return ret;
>>> }
>>> 
>>> -static void pblk_bio_map_addr_endio(struct bio *bio)
>>> -{
>>> -     bio_put(bio);
>>> -}
>>> -
>>> -struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
>>> -                           unsigned int nr_secs, unsigned int len,
>>> -                           int alloc_type, gfp_t gfp_mask)
>>> -{
>>> -     struct nvm_tgt_dev *dev = pblk->dev;
>>> -     void *kaddr = data;
>>> -     struct page *page;
>>> -     struct bio *bio;
>>> -     int i, ret;
>>> -
>>> -     if (alloc_type == PBLK_KMALLOC_META)
>>> -             return bio_map_kern(dev->q, kaddr, len, gfp_mask);
>>> -
>>> -     bio = bio_kmalloc(gfp_mask, nr_secs);
>>> -     if (!bio)
>>> -             return ERR_PTR(-ENOMEM);
>>> -
>>> -     for (i = 0; i < nr_secs; i++) {
>>> -             page = vmalloc_to_page(kaddr);
>>> -             if (!page) {
>>> -                     pblk_err(pblk, "could not map vmalloc bio\n");
>>> -                     bio_put(bio);
>>> -                     bio = ERR_PTR(-ENOMEM);
>>> -                     goto out;
>>> -             }
>>> -
>>> -             ret = bio_add_pc_page(dev->q, bio, page, PAGE_SIZE, 0);
>>> -             if (ret != PAGE_SIZE) {
>>> -                     pblk_err(pblk, "could not add page to bio\n");
>>> -                     bio_put(bio);
>>> -                     bio = ERR_PTR(-ENOMEM);
>>> -                     goto out;
>>> -             }
>>> -
>>> -             kaddr += PAGE_SIZE;
>>> -     }
>>> -
>>> -     bio->bi_end_io = pblk_bio_map_addr_endio;
>>> -out:
>>> -     return bio;
>>> -}
>>> -
>>> int pblk_calc_secs(struct pblk *pblk, unsigned long secs_avail,
>>>                 unsigned long secs_to_flush, bool skip_meta)
>>> {
>>> @@ -722,9 +676,7 @@ u64 pblk_line_smeta_start(struct pblk *pblk, struct pblk_line *line)
>>> 
>>> int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
>>> {
>>> -     struct nvm_tgt_dev *dev = pblk->dev;
>>>      struct pblk_line_meta *lm = &pblk->lm;
>>> -     struct bio *bio;
>>>      struct ppa_addr *ppa_list;
>>>      struct nvm_rq rqd;
>>>      u64 paddr = pblk_line_smeta_start(pblk, line);
>>> @@ -736,16 +688,6 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
>>>      if (ret)
>>>              return ret;
>>> 
>>> -     bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
>>> -     if (IS_ERR(bio)) {
>>> -             ret = PTR_ERR(bio);
>>> -             goto clear_rqd;
>>> -     }
>>> -
>>> -     bio->bi_iter.bi_sector = 0; /* internal bio */
>>> -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
>>> -
>>> -     rqd.bio = bio;
>>>      rqd.opcode = NVM_OP_PREAD;
>>>      rqd.nr_ppas = lm->smeta_sec;
>>>      rqd.is_seq = 1;
>>> @@ -754,10 +696,9 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
>>>      for (i = 0; i < lm->smeta_sec; i++, paddr++)
>>>              ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line->id);
>>> 
>>> -     ret = pblk_submit_io_sync(pblk, &rqd);
>>> +     ret = pblk_submit_io_sync(pblk, &rqd, line->smeta);
>>>      if (ret) {
>>>              pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
>>> -             bio_put(bio);
>>>              goto clear_rqd;
>>>      }
>>> 
>>> @@ -776,9 +717,7 @@ int pblk_line_smeta_read(struct pblk *pblk, struct pblk_line *line)
>>> static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
>>>                               u64 paddr)
>>> {
>>> -     struct nvm_tgt_dev *dev = pblk->dev;
>>>      struct pblk_line_meta *lm = &pblk->lm;
>>> -     struct bio *bio;
>>>      struct ppa_addr *ppa_list;
>>>      struct nvm_rq rqd;
>>>      __le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
>>> @@ -791,16 +730,6 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
>>>      if (ret)
>>>              return ret;
>>> 
>>> -     bio = bio_map_kern(dev->q, line->smeta, lm->smeta_len, GFP_KERNEL);
>>> -     if (IS_ERR(bio)) {
>>> -             ret = PTR_ERR(bio);
>>> -             goto clear_rqd;
>>> -     }
>>> -
>>> -     bio->bi_iter.bi_sector = 0; /* internal bio */
>>> -     bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
>>> -
>>> -     rqd.bio = bio;
>>>      rqd.opcode = NVM_OP_PWRITE;
>>>      rqd.nr_ppas = lm->smeta_sec;
>>>      rqd.is_seq = 1;
>>> @@ -814,10 +743,9 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line,
>>>              meta->lba = lba_list[paddr] = addr_empty;
>>>      }
>>> 
>>> -     ret = pblk_submit_io_sync_sem(pblk, &rqd);
>>> +     ret = pblk_submit_io_sync_sem(pblk, &rqd, line->smeta);
>>>      if (ret) {
>>>              pblk_err(pblk, "smeta I/O submission failed: %d\n", ret);
>>> -             bio_put(bio);
>>>              goto clear_rqd;
>>>      }
>>> 
>>> @@ -838,10 +766,8 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
>>> {
>>>      struct nvm_tgt_dev *dev = pblk->dev;
>>>      struct nvm_geo *geo = &dev->geo;
>>> -     struct pblk_line_mgmt *l_mg = &pblk->l_mg;
>>>      struct pblk_line_meta *lm = &pblk->lm;
>>>      void *ppa_list_buf, *meta_list;
>>> -     struct bio *bio;
>>>      struct ppa_addr *ppa_list;
>>>      struct nvm_rq rqd;
>>>      u64 paddr = line->emeta_ssec;
>>> @@ -867,17 +793,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
>>>      rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
>>>      rq_len = rq_ppas * geo->csecs;
>>> 
>>> -     bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len,
>>> -                                     l_mg->emeta_alloc_type, GFP_KERNEL);
>>> -     if (IS_ERR(bio)) {
>>> -             ret = PTR_ERR(bio);
>>> -             goto free_rqd_dma;
>>> -     }
>>> -
>>> -     bio->bi_iter.bi_sector = 0; /* internal bio */
>>> -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
>>> -
>>> -     rqd.bio = bio;
>>>      rqd.meta_list = meta_list;
>>>      rqd.ppa_list = ppa_list_buf;
>>>      rqd.dma_meta_list = dma_meta_list;
>>> @@ -896,7 +811,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
>>>              while (test_bit(pos, line->blk_bitmap)) {
>>>                      paddr += min;
>>>                      if (pblk_boundary_paddr_checks(pblk, paddr)) {
>>> -                             bio_put(bio);
>>>                              ret = -EINTR;
>>>                              goto free_rqd_dma;
>>>                      }
>>> @@ -906,7 +820,6 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
>>>              }
>>> 
>>>              if (pblk_boundary_paddr_checks(pblk, paddr + min)) {
>>> -                     bio_put(bio);
>>>                      ret = -EINTR;
>>>                      goto free_rqd_dma;
>>>              }
>>> @@ -915,10 +828,9 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
>>>                      ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line_id);
>>>      }
>>> 
>>> -     ret = pblk_submit_io_sync(pblk, &rqd);
>>> +     ret = pblk_submit_io_sync(pblk, &rqd, emeta_buf);
>>>      if (ret) {
>>>              pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
>>> -             bio_put(bio);
>>>              goto free_rqd_dma;
>>>      }
>>> 
>>> @@ -963,7 +875,7 @@ static int pblk_blk_erase_sync(struct pblk *pblk, struct ppa_addr ppa)
>>>      /* The write thread schedules erases so that it minimizes disturbances
>>>       * with writes. Thus, there is no need to take the LUN semaphore.
>>>       */
>>> -     ret = pblk_submit_io_sync(pblk, &rqd);
>>> +     ret = pblk_submit_io_sync(pblk, &rqd, NULL);
>>>      rqd.private = pblk;
>>>      __pblk_end_io_erase(pblk, &rqd);
>>> 
>>> @@ -1792,7 +1704,7 @@ int pblk_blk_erase_async(struct pblk *pblk, struct ppa_addr ppa)
>>>      /* The write thread schedules erases so that it minimizes disturbances
>>>       * with writes. Thus, there is no need to take the LUN semaphore.
>>>       */
>>> -     err = pblk_submit_io(pblk, rqd);
>>> +     err = pblk_submit_io(pblk, rqd, NULL);
>>>      if (err) {
>>>              struct nvm_tgt_dev *dev = pblk->dev;
>>>              struct nvm_geo *geo = &dev->geo;
>>> @@ -1923,7 +1835,6 @@ void pblk_line_close_meta(struct pblk *pblk, struct pblk_line *line)
>>> static void pblk_save_lba_list(struct pblk *pblk, struct pblk_line *line)
>>> {
>>>      struct pblk_line_meta *lm = &pblk->lm;
>>> -     struct pblk_line_mgmt *l_mg = &pblk->l_mg;
>>>      unsigned int lba_list_size = lm->emeta_len[2];
>>>      struct pblk_w_err_gc *w_err_gc = line->w_err_gc;
>>>      struct pblk_emeta *emeta = line->emeta;
>>> diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c
>>> index d98ea392fe33..d572d4559e4e 100644
>>> --- a/drivers/lightnvm/pblk-read.c
>>> +++ b/drivers/lightnvm/pblk-read.c
>>> @@ -342,7 +342,7 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio)
>>>              bio_put(int_bio);
>>>              int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set);
>>>              goto split_retry;
>>> -     } else if (pblk_submit_io(pblk, rqd)) {
>>> +     } else if (pblk_submit_io(pblk, rqd, NULL)) {
>>>              /* Submitting IO to drive failed, let's report an error */
>>>              rqd->error = -ENODEV;
>>>              pblk_end_io_read(rqd);
>>> @@ -419,7 +419,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
>>> {
>>>      struct nvm_tgt_dev *dev = pblk->dev;
>>>      struct nvm_geo *geo = &dev->geo;
>>> -     struct bio *bio;
>>>      struct nvm_rq rqd;
>>>      int data_len;
>>>      int ret = NVM_IO_OK;
>>> @@ -447,25 +446,12 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
>>>              goto out;
>>> 
>>>      data_len = (gc_rq->secs_to_gc) * geo->csecs;
>>> -     bio = pblk_bio_map_addr(pblk, gc_rq->data, gc_rq->secs_to_gc, data_len,
>>> -                                             PBLK_VMALLOC_META, GFP_KERNEL);
>>> -     if (IS_ERR(bio)) {
>>> -             pblk_err(pblk, "could not allocate GC bio (%lu)\n",
>>> -                                                             PTR_ERR(bio));
>>> -             ret = PTR_ERR(bio);
>>> -             goto err_free_dma;
>>> -     }
>>> -
>>> -     bio->bi_iter.bi_sector = 0; /* internal bio */
>>> -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
>>> -
>>>      rqd.opcode = NVM_OP_PREAD;
>>>      rqd.nr_ppas = gc_rq->secs_to_gc;
>>> -     rqd.bio = bio;
>>> 
>>> -     if (pblk_submit_io_sync(pblk, &rqd)) {
>>> +     if (pblk_submit_io_sync(pblk, &rqd, gc_rq->data)) {
>>>              ret = -EIO;
>>> -             goto err_free_bio;
>>> +             goto err_free_dma;
>>>      }
>>> 
>>>      pblk_read_check_rand(pblk, &rqd, gc_rq->lba_list, gc_rq->nr_secs);
>>> @@ -489,8 +475,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
>>>      pblk_free_rqd_meta(pblk, &rqd);
>>>      return ret;
>>> 
>>> -err_free_bio:
>>> -     bio_put(bio);
>>> err_free_dma:
>>>      pblk_free_rqd_meta(pblk, &rqd);
>>>      return ret;
>>> diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
>>> index e6dda04de144..d5e210c3c5b7 100644
>>> --- a/drivers/lightnvm/pblk-recovery.c
>>> +++ b/drivers/lightnvm/pblk-recovery.c
>>> @@ -178,12 +178,11 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
>>>      void *meta_list;
>>>      struct pblk_pad_rq *pad_rq;
>>>      struct nvm_rq *rqd;
>>> -     struct bio *bio;
>>>      struct ppa_addr *ppa_list;
>>>      void *data;
>>>      __le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
>>>      u64 w_ptr = line->cur_sec;
>>> -     int left_line_ppas, rq_ppas, rq_len;
>>> +     int left_line_ppas, rq_ppas;
>>>      int i, j;
>>>      int ret = 0;
>>> 
>>> @@ -212,28 +211,15 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
>>>              goto fail_complete;
>>>      }
>>> 
>>> -     rq_len = rq_ppas * geo->csecs;
>>> -
>>> -     bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
>>> -                                             PBLK_VMALLOC_META, GFP_KERNEL);
>>> -     if (IS_ERR(bio)) {
>>> -             ret = PTR_ERR(bio);
>>> -             goto fail_complete;
>>> -     }
>>> -
>>> -     bio->bi_iter.bi_sector = 0; /* internal bio */
>>> -     bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
>>> -
>>>      rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT);
>>> 
>>>      ret = pblk_alloc_rqd_meta(pblk, rqd);
>>>      if (ret) {
>>>              pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
>>> -             bio_put(bio);
>>>              goto fail_complete;
>>>      }
>>> 
>>> -     rqd->bio = bio;
>>> +     rqd->bio = NULL;
>>>      rqd->opcode = NVM_OP_PWRITE;
>>>      rqd->is_seq = 1;
>>>      rqd->nr_ppas = rq_ppas;
>>> @@ -275,13 +261,12 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
>>>      kref_get(&pad_rq->ref);
>>>      pblk_down_chunk(pblk, ppa_list[0]);
>>> 
>>> -     ret = pblk_submit_io(pblk, rqd);
>>> +     ret = pblk_submit_io(pblk, rqd, data);
>>>      if (ret) {
>>>              pblk_err(pblk, "I/O submission failed: %d\n", ret);
>>>              pblk_up_chunk(pblk, ppa_list[0]);
>>>              kref_put(&pad_rq->ref, pblk_recov_complete);
>>>              pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
>>> -             bio_put(bio);
>>>              goto fail_complete;
>>>      }
>>> 
>>> @@ -375,7 +360,6 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
>>>      struct ppa_addr *ppa_list;
>>>      void *meta_list;
>>>      struct nvm_rq *rqd;
>>> -     struct bio *bio;
>>>      void *data;
>>>      dma_addr_t dma_ppa_list, dma_meta_list;
>>>      __le64 *lba_list;
>>> @@ -407,15 +391,7 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
>>>      rq_len = rq_ppas * geo->csecs;
>>> 
>>> retry_rq:
>>> -     bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL);
>>> -     if (IS_ERR(bio))
>>> -             return PTR_ERR(bio);
>>> -
>>> -     bio->bi_iter.bi_sector = 0; /* internal bio */
>>> -     bio_set_op_attrs(bio, REQ_OP_READ, 0);
>>> -     bio_get(bio);
>>> -
>>> -     rqd->bio = bio;
>>> +     rqd->bio = NULL;
>>>      rqd->opcode = NVM_OP_PREAD;
>>>      rqd->meta_list = meta_list;
>>>      rqd->nr_ppas = rq_ppas;
>>> @@ -445,10 +421,9 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
>>>                              addr_to_gen_ppa(pblk, paddr + j, line->id);
>>>      }
>>> 
>>> -     ret = pblk_submit_io_sync(pblk, rqd);
>>> +     ret = pblk_submit_io_sync(pblk, rqd, data);
>>>      if (ret) {
>>>              pblk_err(pblk, "I/O submission failed: %d\n", ret);
>>> -             bio_put(bio);
>>>              return ret;
>>>      }
>>> 
>>> @@ -460,24 +435,20 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
>>> 
>>>              if (padded) {
>>>                      pblk_log_read_err(pblk, rqd);
>>> -                     bio_put(bio);
>>>                      return -EINTR;
>>>              }
>>> 
>>>              pad_distance = pblk_pad_distance(pblk, line);
>>>              ret = pblk_recov_pad_line(pblk, line, pad_distance);
>>>              if (ret) {
>>> -                     bio_put(bio);
>>>                      return ret;
>>>              }
>>> 
>>>              padded = true;
>>> -             bio_put(bio);
>>>              goto retry_rq;
>>>      }
>>> 
>>>      pblk_get_packed_meta(pblk, rqd);
>>> -     bio_put(bio);
>>> 
>>>      for (i = 0; i < rqd->nr_ppas; i++) {
>>>              struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i);
>>> diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
>>> index 4e63f9b5954c..b9a2aeba95ab 100644
>>> --- a/drivers/lightnvm/pblk-write.c
>>> +++ b/drivers/lightnvm/pblk-write.c
>>> @@ -373,7 +373,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
>>>      struct pblk_emeta *emeta = meta_line->emeta;
>>>      struct ppa_addr *ppa_list;
>>>      struct pblk_g_ctx *m_ctx;
>>> -     struct bio *bio;
>>>      struct nvm_rq *rqd;
>>>      void *data;
>>>      u64 paddr;
>>> @@ -391,20 +390,9 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
>>>      rq_len = rq_ppas * geo->csecs;
>>>      data = ((void *)emeta->buf) + emeta->mem;
>>> 
>>> -     bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
>>> -                                     l_mg->emeta_alloc_type, GFP_KERNEL);
>>> -     if (IS_ERR(bio)) {
>>> -             pblk_err(pblk, "failed to map emeta io");
>>> -             ret = PTR_ERR(bio);
>>> -             goto fail_free_rqd;
>>> -     }
>>> -     bio->bi_iter.bi_sector = 0; /* internal bio */
>>> -     bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
>>> -     rqd->bio = bio;
>>> -
>>>      ret = pblk_alloc_w_rq(pblk, rqd, rq_ppas, pblk_end_io_write_meta);
>>>      if (ret)
>>> -             goto fail_free_bio;
>>> +             goto fail_free_rqd;
>>> 
>>>      ppa_list = nvm_rq_to_ppa_list(rqd);
>>>      for (i = 0; i < rqd->nr_ppas; ) {
>>> @@ -423,7 +411,7 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
>>> 
>>>      pblk_down_chunk(pblk, ppa_list[0]);
>>> 
>>> -     ret = pblk_submit_io(pblk, rqd);
>>> +     ret = pblk_submit_io(pblk, rqd, data);
>>>      if (ret) {
>>>              pblk_err(pblk, "emeta I/O submission failed: %d\n", ret);
>>>              goto fail_rollback;
>>> @@ -437,8 +425,6 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
>>>      pblk_dealloc_page(pblk, meta_line, rq_ppas);
>>>      list_add(&meta_line->list, &meta_line->list);
>>>      spin_unlock(&l_mg->close_lock);
>>> -fail_free_bio:
>>> -     bio_put(bio);
>>> fail_free_rqd:
>>>      pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
>>>      return ret;
>>> @@ -523,7 +509,7 @@ static int pblk_submit_io_set(struct pblk *pblk, struct nvm_rq *rqd)
>>>      meta_line = pblk_should_submit_meta_io(pblk, rqd);
>>> 
>>>      /* Submit data write for current data line */
>>> -     err = pblk_submit_io(pblk, rqd);
>>> +     err = pblk_submit_io(pblk, rqd, NULL);
>>>      if (err) {
>>>              pblk_err(pblk, "data I/O submission failed: %d\n", err);
>>>              return NVM_IO_ERR;
>>> diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
>>> index a67855387f53..d515d3409a74 100644
>>> --- a/drivers/lightnvm/pblk.h
>>> +++ b/drivers/lightnvm/pblk.h
>>> @@ -783,14 +783,10 @@ struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk,
>>>                                            struct ppa_addr ppa);
>>> void pblk_log_write_err(struct pblk *pblk, struct nvm_rq *rqd);
>>> void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd);
>>> -int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
>>> -int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd);
>>> -int pblk_submit_io_sync_sem(struct pblk *pblk, struct nvm_rq *rqd);
>>> +int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
>>> +int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd, void *buf);
>>> int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line);
>>> void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd);
>>> -struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
>>> -                           unsigned int nr_secs, unsigned int len,
>>> -                           int alloc_type, gfp_t gfp_mask);
>>> struct pblk_line *pblk_line_get(struct pblk *pblk);
>>> struct pblk_line *pblk_line_get_first_data(struct pblk *pblk);
>>> struct pblk_line *pblk_line_replace_data(struct pblk *pblk);
>>> diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
>>> index d6f121452d5d..ec46693f6b64 100644
>>> --- a/drivers/nvme/host/lightnvm.c
>>> +++ b/drivers/nvme/host/lightnvm.c
>>> @@ -667,11 +667,14 @@ static struct request *nvme_nvm_alloc_request(struct request_queue *q,
>>>      return rq;
>>> }
>>> 
>>> -static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
>>> +static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd,
>>> +                           void *buf)
>>> {
>>> +     struct nvm_geo *geo = &dev->geo;
>>>      struct request_queue *q = dev->q;
>>>      struct nvme_nvm_command *cmd;
>>>      struct request *rq;
>>> +     int ret;
>>> 
>>>      cmd = kzalloc(sizeof(struct nvme_nvm_command), GFP_KERNEL);
>>>      if (!cmd)
>>> @@ -679,8 +682,15 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
>>> 
>>>      rq = nvme_nvm_alloc_request(q, rqd, cmd);
>>>      if (IS_ERR(rq)) {
>>> -             kfree(cmd);
>>> -             return PTR_ERR(rq);
>>> +             ret = PTR_ERR(rq);
>>> +             goto err_free_cmd;
>>> +     }
>>> +
>>> +     if (buf) {
>>> +             ret = blk_rq_map_kern(q, rq, buf, geo->csecs * rqd->nr_ppas,
>>> +                             GFP_KERNEL);
>>> +             if (ret)
>>> +                     goto err_free_cmd;
>>>      }
>>> 
>>>      rq->end_io_data = rqd;
>>> @@ -688,6 +698,10 @@ static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
>>>      blk_execute_rq_nowait(q, NULL, rq, 0, nvme_nvm_end_io);
>>> 
>>>      return 0;
>>> +
>>> +err_free_cmd:
>>> +     kfree(cmd);
>>> +     return ret;
>>> }
>>> 
>>> static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name,
>>> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
>>> index 8891647b24b1..ee8ec2e68055 100644
>>> --- a/include/linux/lightnvm.h
>>> +++ b/include/linux/lightnvm.h
>>> @@ -88,7 +88,7 @@ typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *);
>>> typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
>>> typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, sector_t, int,
>>>                                                      struct nvm_chk_meta *);
>>> -typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
>>> +typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *, void *);
>>> typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *, int);
>>> typedef void (nvm_destroy_dma_pool_fn)(void *);
>>> typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
>>> @@ -680,8 +680,8 @@ extern int nvm_get_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr,
>>>                            int, struct nvm_chk_meta *);
>>> extern int nvm_set_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr *,
>>>                            int, int);
>>> -extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *);
>>> -extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *);
>>> +extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *, void *);
>>> +extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *, void *);
>>> extern void nvm_end_io(struct nvm_rq *);
>>> 
>>> #else /* CONFIG_NVM */
>>> --
>>> 2.7.4
>> 
>> It’s very good to get rid of pblk_bio_map_addr(). Need to look at this
>> closer because I remember a number of corner cases due to the metadata
>> allocation. Have you tested the vmalloc allocation path? Note that you
>> need big lines for this to happen as it will try to do kmalloc if
>> possible
> 
> Yeah, i checked that vmalloc worked for the emeta buffers(by switching
> over manually), so we should be good.
> 

Cool. Code looks good otherwise.

Reviewed-by: Javier González <javier@javigon.com>



[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn
  2019-07-31  9:41 ` [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn Hans Holmberg
  2019-07-31 13:54   ` Javier González
@ 2019-08-06  7:05   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-06  7:05 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjorling, Christoph Hellwig, Javier González,
	linux-block, linux-kernel

On Wed, Jul 31, 2019 at 11:41:33AM +0200, Hans Holmberg wrote:
> Move the redundant sync handling interface and wait for a completion
> in the lightnvm core instead.
> 
> Signed-off-by: Hans Holmberg <hans@owltronix.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/4] lightnvm: move metadata mapping to lower level driver
  2019-07-31  9:41 ` [PATCH 2/4] lightnvm: move metadata mapping to lower level driver Hans Holmberg
  2019-07-31 13:58   ` Javier González
@ 2019-08-06  7:06   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-06  7:06 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjorling, Christoph Hellwig, Javier González,
	linux-block, linux-kernel

On Wed, Jul 31, 2019 at 11:41:34AM +0200, Hans Holmberg wrote:
> Now that blk_rq_map_kern can map both kmem and vmem, move
> internal metadata mapping down to the lower level driver.
> 
> Signed-off-by: Hans Holmberg <hans@owltronix.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata
  2019-07-31  9:41 ` [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata Hans Holmberg
  2019-07-31 14:00   ` Javier González
@ 2019-08-06  7:06   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-06  7:06 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjorling, Christoph Hellwig, Javier González,
	linux-block, linux-kernel

On Wed, Jul 31, 2019 at 11:41:35AM +0200, Hans Holmberg wrote:
> There is no reason now not to use kvmalloc, so
> so replace the internal metadata allocation scheme.

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/4] block: stop exporting bio_map_kern
  2019-07-31  9:41 ` [PATCH 4/4] block: stop exporting bio_map_kern Hans Holmberg
  2019-07-31 17:13   ` Javier González
@ 2019-08-06  7:07   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-06  7:07 UTC (permalink / raw)
  To: Hans Holmberg
  Cc: Matias Bjorling, Christoph Hellwig, Javier González,
	linux-block, linux-kernel

On Wed, Jul 31, 2019 at 11:41:36AM +0200, Hans Holmberg wrote:
> Now that there no module users left of bio_map_kern, stop
> exporting the symbol.
> 
> Signed-off-by: Hans Holmberg <hans@owltronix.com>

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/4] lnvm/pblk mapping cleanups
  2019-07-31  9:41 [PATCH 0/4] lnvm/pblk mapping cleanups Hans Holmberg
                   ` (3 preceding siblings ...)
  2019-07-31  9:41 ` [PATCH 4/4] block: stop exporting bio_map_kern Hans Holmberg
@ 2019-08-06 13:40 ` Matias Bjørling
  2019-08-06 14:16   ` Jens Axboe
  4 siblings, 1 reply; 17+ messages in thread
From: Matias Bjørling @ 2019-08-06 13:40 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Hans Holmberg, Christoph Hellwig, Javier González,
	linux-block, linux-kernel

On 7/31/19 11:41 AM, Hans Holmberg wrote:
> This series cleans up the metadata allocation/mapping in lnvm/pblk
> by moving over to kvmalloc for metadata and moving metadata mapping
> down to the lower lever driver where blk_rq_map_kern can be used.
> 
> Hans Holmberg (4):
>    lightnvm: remove nvm_submit_io_sync_fn
>    lightnvm: move metadata mapping to lower level driver
>    lightnvm: pblk: use kvmalloc for metadata
>    block: stop exporting bio_map_kern
> 
>   block/bio.c                      |   1 -
>   drivers/lightnvm/core.c          |  43 ++++++++++++---
>   drivers/lightnvm/pblk-core.c     | 116 +++++----------------------------------
>   drivers/lightnvm/pblk-gc.c       |  19 +++----
>   drivers/lightnvm/pblk-init.c     |  38 ++++---------
>   drivers/lightnvm/pblk-read.c     |  22 +-------
>   drivers/lightnvm/pblk-recovery.c |  39 ++-----------
>   drivers/lightnvm/pblk-write.c    |  20 +------
>   drivers/lightnvm/pblk.h          |  31 +----------
>   drivers/nvme/host/lightnvm.c     |  45 +++++----------
>   include/linux/lightnvm.h         |   8 +--
>   11 files changed, 96 insertions(+), 286 deletions(-)
> 

Hi Jens,

Would you like me to pick up this serie, and send it through the 
lightnvm pull request, or would you like to pick it up?

Thank you!
Matias

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/4] lnvm/pblk mapping cleanups
  2019-08-06 13:40 ` [PATCH 0/4] lnvm/pblk mapping cleanups Matias Bjørling
@ 2019-08-06 14:16   ` Jens Axboe
  0 siblings, 0 replies; 17+ messages in thread
From: Jens Axboe @ 2019-08-06 14:16 UTC (permalink / raw)
  To: Matias Bjørling
  Cc: Hans Holmberg, Christoph Hellwig, Javier González,
	linux-block, linux-kernel

On 8/6/19 6:40 AM, Matias Bjørling wrote:
> On 7/31/19 11:41 AM, Hans Holmberg wrote:
>> This series cleans up the metadata allocation/mapping in lnvm/pblk
>> by moving over to kvmalloc for metadata and moving metadata mapping
>> down to the lower lever driver where blk_rq_map_kern can be used.
>>
>> Hans Holmberg (4):
>>     lightnvm: remove nvm_submit_io_sync_fn
>>     lightnvm: move metadata mapping to lower level driver
>>     lightnvm: pblk: use kvmalloc for metadata
>>     block: stop exporting bio_map_kern
>>
>>    block/bio.c                      |   1 -
>>    drivers/lightnvm/core.c          |  43 ++++++++++++---
>>    drivers/lightnvm/pblk-core.c     | 116 +++++----------------------------------
>>    drivers/lightnvm/pblk-gc.c       |  19 +++----
>>    drivers/lightnvm/pblk-init.c     |  38 ++++---------
>>    drivers/lightnvm/pblk-read.c     |  22 +-------
>>    drivers/lightnvm/pblk-recovery.c |  39 ++-----------
>>    drivers/lightnvm/pblk-write.c    |  20 +------
>>    drivers/lightnvm/pblk.h          |  31 +----------
>>    drivers/nvme/host/lightnvm.c     |  45 +++++----------
>>    include/linux/lightnvm.h         |   8 +--
>>    11 files changed, 96 insertions(+), 286 deletions(-)
>>
> 
> Hi Jens,
> 
> Would you like me to pick up this serie, and send it through the
> lightnvm pull request, or would you like to pick it up?

I can apply it directly for 5.4.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-08-06 14:16 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-31  9:41 [PATCH 0/4] lnvm/pblk mapping cleanups Hans Holmberg
2019-07-31  9:41 ` [PATCH 1/4] lightnvm: remove nvm_submit_io_sync_fn Hans Holmberg
2019-07-31 13:54   ` Javier González
2019-08-06  7:05   ` Christoph Hellwig
2019-07-31  9:41 ` [PATCH 2/4] lightnvm: move metadata mapping to lower level driver Hans Holmberg
2019-07-31 13:58   ` Javier González
2019-08-01  7:15     ` Hans Holmberg
2019-08-01  7:46       ` Javier González
2019-08-06  7:06   ` Christoph Hellwig
2019-07-31  9:41 ` [PATCH 3/4] lightnvm: pblk: use kvmalloc for metadata Hans Holmberg
2019-07-31 14:00   ` Javier González
2019-08-06  7:06   ` Christoph Hellwig
2019-07-31  9:41 ` [PATCH 4/4] block: stop exporting bio_map_kern Hans Holmberg
2019-07-31 17:13   ` Javier González
2019-08-06  7:07   ` Christoph Hellwig
2019-08-06 13:40 ` [PATCH 0/4] lnvm/pblk mapping cleanups Matias Bjørling
2019-08-06 14:16   ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).