mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Matias Bjørling" <mb@lightnvm.io>
To: axboe@fb.com
Cc: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
	keith.busch@intel.com, javier@cnexlabs.com,
	"Javier González" <jg@lightnvm.io>,
	"Matias Bjørling" <mb@lightnvm.io>
Subject: [GIT PULL 12/37] lightnvm: pblk: refactor bad block identification
Date: Fri, 30 Mar 2018 00:04:59 +0200	[thread overview]
Message-ID: <20180329220524.30363-13-mb@lightnvm.io> (raw)
In-Reply-To: <20180329220524.30363-1-mb@lightnvm.io>

From: Javier González <jg@lightnvm.io>

In preparation for the OCSSD 2.0 spec. bad block identification,
refactor the current code to generalize bad block get/set functions and
structures.

Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
---
 drivers/lightnvm/pblk-core.c |   3 -
 drivers/lightnvm/pblk-init.c | 211 ++++++++++++++++++++++---------------------
 drivers/lightnvm/pblk.h      |   6 --
 3 files changed, 110 insertions(+), 110 deletions(-)

diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 8848443a0721..5c363ccde0e3 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1025,7 +1025,6 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
 	struct nvm_geo *geo = &dev->geo;
 	struct pblk_line_meta *lm = &pblk->lm;
 	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
-	int nr_bb = 0;
 	u64 off;
 	int bit = -1;
 	int emeta_secs;
@@ -1041,8 +1040,6 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
 		bitmap_or(line->map_bitmap, line->map_bitmap, l_mg->bb_aux,
 							lm->sec_per_line);
 		line->sec_in_line -= geo->sec_per_chk;
-		if (bit >= lm->emeta_bb)
-			nr_bb++;
 	}
 
 	/* Mark smeta metadata sectors as bad sectors */
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 49c65f1dd48b..141036bd6afa 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -365,7 +365,25 @@ static void pblk_luns_free(struct pblk *pblk)
 	kfree(pblk->luns);
 }
 
-static void pblk_free_line_bitmaps(struct pblk_line *line)
+static void pblk_line_mg_free(struct pblk *pblk)
+{
+	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
+	int i;
+
+	kfree(l_mg->bb_template);
+	kfree(l_mg->bb_aux);
+	kfree(l_mg->vsc_list);
+
+	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);
+		kfree(l_mg->eline_meta[i]);
+	}
+
+	kfree(pblk->lines);
+}
+
+static void pblk_line_meta_free(struct pblk_line *line)
 {
 	kfree(line->blk_bitmap);
 	kfree(line->erase_bitmap);
@@ -382,40 +400,16 @@ static void pblk_lines_free(struct pblk *pblk)
 		line = &pblk->lines[i];
 
 		pblk_line_free(pblk, line);
-		pblk_free_line_bitmaps(line);
+		pblk_line_meta_free(line);
 	}
 	spin_unlock(&l_mg->free_lock);
 }
 
-static void pblk_line_meta_free(struct pblk *pblk)
+static int pblk_bb_get_tbl(struct nvm_tgt_dev *dev, struct pblk_lun *rlun,
+			   u8 *blks, int nr_blks)
 {
-	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
-	int i;
-
-	kfree(l_mg->bb_template);
-	kfree(l_mg->bb_aux);
-	kfree(l_mg->vsc_list);
-
-	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);
-		kfree(l_mg->eline_meta[i]);
-	}
-
-	kfree(pblk->lines);
-}
-
-static int pblk_bb_discovery(struct nvm_tgt_dev *dev, struct pblk_lun *rlun)
-{
-	struct nvm_geo *geo = &dev->geo;
 	struct ppa_addr ppa;
-	u8 *blks;
-	int nr_blks, ret;
-
-	nr_blks = geo->nr_chks * geo->plane_mode;
-	blks = kmalloc(nr_blks, GFP_KERNEL);
-	if (!blks)
-		return -ENOMEM;
+	int ret;
 
 	ppa.ppa = 0;
 	ppa.g.ch = rlun->bppa.g.ch;
@@ -423,34 +417,56 @@ static int pblk_bb_discovery(struct nvm_tgt_dev *dev, struct pblk_lun *rlun)
 
 	ret = nvm_get_tgt_bb_tbl(dev, ppa, blks);
 	if (ret)
-		goto out;
+		return ret;
 
 	nr_blks = nvm_bb_tbl_fold(dev->parent, blks, nr_blks);
-	if (nr_blks < 0) {
-		ret = nr_blks;
-		goto out;
-	}
-
-	rlun->bb_list = blks;
+	if (nr_blks < 0)
+		return -EIO;
 
 	return 0;
-out:
-	kfree(blks);
-	return ret;
+}
+
+static void *pblk_bb_get_log(struct pblk *pblk)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	u8 *log;
+	int i, nr_blks, blk_per_lun;
+	int ret;
+
+	blk_per_lun = geo->nr_chks * geo->plane_mode;
+	nr_blks = blk_per_lun * geo->all_luns;
+
+	log = kmalloc(nr_blks, GFP_KERNEL);
+	if (!log)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < geo->all_luns; i++) {
+		struct pblk_lun *rlun = &pblk->luns[i];
+		u8 *log_pos = log + i * blk_per_lun;
+
+		ret = pblk_bb_get_tbl(dev, rlun, log_pos, blk_per_lun);
+		if (ret) {
+			kfree(log);
+			return ERR_PTR(-EIO);
+		}
+	}
+
+	return log;
 }
 
 static int pblk_bb_line(struct pblk *pblk, struct pblk_line *line,
-			int blk_per_line)
+			u8 *bb_log, int blk_per_line)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
-	struct pblk_lun *rlun;
-	int bb_cnt = 0;
-	int i;
+	int i, bb_cnt = 0;
 
 	for (i = 0; i < blk_per_line; i++) {
-		rlun = &pblk->luns[i];
-		if (rlun->bb_list[line->id] == NVM_BLK_T_FREE)
+		struct pblk_lun *rlun = &pblk->luns[i];
+		u8 *lun_bb_log = bb_log + i * blk_per_line;
+
+		if (lun_bb_log[line->id] == NVM_BLK_T_FREE)
 			continue;
 
 		set_bit(pblk_ppa_to_pos(geo, rlun->bppa), line->blk_bitmap);
@@ -460,29 +476,12 @@ static int pblk_bb_line(struct pblk *pblk, struct pblk_line *line,
 	return bb_cnt;
 }
 
-static int pblk_alloc_line_bitmaps(struct pblk *pblk, struct pblk_line *line)
-{
-	struct pblk_line_meta *lm = &pblk->lm;
-
-	line->blk_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
-	if (!line->blk_bitmap)
-		return -ENOMEM;
-
-	line->erase_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
-	if (!line->erase_bitmap) {
-		kfree(line->blk_bitmap);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
 static int pblk_luns_init(struct pblk *pblk, struct ppa_addr *luns)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
 	struct pblk_lun *rlun;
-	int i, ret;
+	int i;
 
 	/* TODO: Implement unbalanced LUN support */
 	if (geo->nr_luns < 0) {
@@ -505,13 +504,6 @@ static int pblk_luns_init(struct pblk *pblk, struct ppa_addr *luns)
 		rlun->bppa = luns[lunid];
 
 		sema_init(&rlun->wr_sem, 1);
-
-		ret = pblk_bb_discovery(dev, rlun);
-		if (ret) {
-			while (--i >= 0)
-				kfree(pblk->luns[i].bb_list);
-			return ret;
-		}
 	}
 
 	return 0;
@@ -689,6 +681,26 @@ static int pblk_lines_alloc_metadata(struct pblk *pblk)
 	return -ENOMEM;
 }
 
+static int pblk_setup_line_meta(struct pblk *pblk, struct pblk_line *line,
+				void *chunk_log, long *nr_bad_blks)
+{
+	struct pblk_line_meta *lm = &pblk->lm;
+
+	line->blk_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
+	if (!line->blk_bitmap)
+		return -ENOMEM;
+
+	line->erase_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
+	if (!line->erase_bitmap) {
+		kfree(line->blk_bitmap);
+		return -ENOMEM;
+	}
+
+	*nr_bad_blks = pblk_bb_line(pblk, line, chunk_log, lm->blk_per_line);
+
+	return 0;
+}
+
 static int pblk_lines_init(struct pblk *pblk)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
@@ -696,8 +708,9 @@ static int pblk_lines_init(struct pblk *pblk)
 	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	struct pblk_line_meta *lm = &pblk->lm;
 	struct pblk_line *line;
+	void *chunk_log;
 	unsigned int smeta_len, emeta_len;
-	long nr_bad_blks, nr_free_blks;
+	long nr_bad_blks = 0, nr_free_blks = 0;
 	int bb_distance, max_write_ppas, mod;
 	int i, ret;
 
@@ -771,13 +784,12 @@ static int pblk_lines_init(struct pblk *pblk)
 	if (lm->min_blk_line > lm->blk_per_line) {
 		pr_err("pblk: config. not supported. Min. LUN in line:%d\n",
 							lm->blk_per_line);
-		ret = -EINVAL;
-		goto fail;
+		return -EINVAL;
 	}
 
 	ret = pblk_lines_alloc_metadata(pblk);
 	if (ret)
-		goto fail;
+		return ret;
 
 	l_mg->bb_template = kzalloc(lm->sec_bitmap_len, GFP_KERNEL);
 	if (!l_mg->bb_template) {
@@ -821,9 +833,16 @@ static int pblk_lines_init(struct pblk *pblk)
 		goto fail_free_bb_aux;
 	}
 
-	nr_free_blks = 0;
+	chunk_log = pblk_bb_get_log(pblk);
+	if (IS_ERR(chunk_log)) {
+		pr_err("pblk: could not get bad block log (%lu)\n",
+							PTR_ERR(chunk_log));
+		ret = PTR_ERR(chunk_log);
+		goto fail_free_bb_aux;
+	}
+
 	for (i = 0; i < l_mg->nr_lines; i++) {
-		int blk_in_line;
+		int chk_in_line;
 
 		line = &pblk->lines[i];
 
@@ -835,26 +854,20 @@ static int pblk_lines_init(struct pblk *pblk)
 		line->vsc = &l_mg->vsc_list[i];
 		spin_lock_init(&line->lock);
 
-		ret = pblk_alloc_line_bitmaps(pblk, line);
+		ret = pblk_setup_line_meta(pblk, line, chunk_log, &nr_bad_blks);
 		if (ret)
-			goto fail_free_lines;
+			goto fail_free_chunk_log;
 
-		nr_bad_blks = pblk_bb_line(pblk, line, lm->blk_per_line);
-		if (nr_bad_blks < 0 || nr_bad_blks > lm->blk_per_line) {
-			pblk_free_line_bitmaps(line);
-			ret = -EINVAL;
-			goto fail_free_lines;
-		}
-
-		blk_in_line = lm->blk_per_line - nr_bad_blks;
-		if (blk_in_line < lm->min_blk_line) {
+		chk_in_line = lm->blk_per_line - nr_bad_blks;
+		if (nr_bad_blks < 0 || nr_bad_blks > lm->blk_per_line ||
+					chk_in_line < lm->min_blk_line) {
 			line->state = PBLK_LINESTATE_BAD;
 			list_add_tail(&line->list, &l_mg->bad_list);
 			continue;
 		}
 
-		nr_free_blks += blk_in_line;
-		atomic_set(&line->blk_in_line, blk_in_line);
+		nr_free_blks += chk_in_line;
+		atomic_set(&line->blk_in_line, chk_in_line);
 
 		l_mg->nr_free_lines++;
 		list_add_tail(&line->list, &l_mg->free_list);
@@ -862,23 +875,19 @@ static int pblk_lines_init(struct pblk *pblk)
 
 	pblk_set_provision(pblk, nr_free_blks);
 
-	/* Cleanup per-LUN bad block lists - managed within lines on run-time */
-	for (i = 0; i < geo->all_luns; i++)
-		kfree(pblk->luns[i].bb_list);
-
+	kfree(chunk_log);
 	return 0;
-fail_free_lines:
+
+fail_free_chunk_log:
+	kfree(chunk_log);
 	while (--i >= 0)
-		pblk_free_line_bitmaps(&pblk->lines[i]);
+		pblk_line_meta_free(&pblk->lines[i]);
 fail_free_bb_aux:
 	kfree(l_mg->bb_aux);
 fail_free_bb_template:
 	kfree(l_mg->bb_template);
 fail_free_meta:
-	pblk_line_meta_free(pblk);
-fail:
-	for (i = 0; i < geo->all_luns; i++)
-		kfree(pblk->luns[i].bb_list);
+	pblk_line_mg_free(pblk);
 
 	return ret;
 }
@@ -922,7 +931,7 @@ static void pblk_free(struct pblk *pblk)
 	pblk_luns_free(pblk);
 	pblk_lines_free(pblk);
 	kfree(pblk->pad_dist);
-	pblk_line_meta_free(pblk);
+	pblk_line_mg_free(pblk);
 	pblk_core_free(pblk);
 	pblk_l2p_free(pblk);
 
@@ -1110,7 +1119,7 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
 fail_free_pad_dist:
 	kfree(pblk->pad_dist);
 fail_free_line_meta:
-	pblk_line_meta_free(pblk);
+	pblk_line_mg_free(pblk);
 fail_free_luns:
 	pblk_luns_free(pblk);
 fail:
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 17e2f242f7da..f0309d8172c0 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -201,12 +201,6 @@ struct pblk_rb {
 
 struct pblk_lun {
 	struct ppa_addr bppa;
-
-	u8 *bb_list;			/* Bad block list for LUN. Only used on
-					 * bring up. Bad blocks are managed
-					 * within lines on run-time.
-					 */
-
 	struct semaphore wr_sem;
 };
 
-- 
2.11.0

  parent reply	other threads:[~2018-03-29 22:07 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-29 22:04 [GIT PULL 00/37] lightnvm patches for 4.17 Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 01/37] lightnvm/pblk-gc: Delete an error message for a failed memory allocation in pblk_gc_line_prepare_ws() Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 02/37] lightnvm: remove chnl_offset in nvme_nvm_identity Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 03/37] lightnvm: pblk: handle bad sectors in the emeta area correctly Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 04/37] lightnvm: pblk: check data lines version on recovery Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 05/37] lightnvm: pblk: export write amplification counters to sysfs Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 06/37] lightnvm: remove mlc pairs structure Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 07/37] lightnvm: remove multiple groups in 1.2 data structure Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 08/37] lightnvm: pblk: add padding distribution sysfs attribute Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 09/37] lightnvm: pblk: delete writer kick timer before stopping thread Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 10/37] lightnvm: pblk: allow allocation of new lines during shutdown Matias Bjørling
2018-03-29 22:04 ` [GIT PULL 11/37] lightnvm: pblk: prevent race in pblk_rb_flush_point_set Matias Bjørling
2018-03-29 22:04 ` Matias Bjørling [this message]
2018-03-29 22:05 ` [GIT PULL 13/37] lightnvm: make 1.2 data structures explicit Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 14/37] lightnvm: flatten nvm_id_group into nvm_id Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 15/37] lightnvm: add 2.0 geometry identification Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 16/37] lightnvm: remove max_rq_size Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 17/37] lightnvm: remove nvm_dev_ops->max_phys_sect Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 18/37] nvme: lightnvm: add late setup of block size and metadata Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 19/37] lightnvm: fix bad block initialization Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 20/37] lightnvm: centralize permission check for lightnvm ioctl Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 21/37] lightnvm: Avoid validation of default op value Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 22/37] lightnvm: pblk: refactor init/exit sequences Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 23/37] lightnvm: simplify geometry structure Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 24/37] lightnvm: add minor version to generic geometry Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 25/37] lightnvm: add shorten OCSSD version in geo Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 26/37] lightnvm: complete geo structure with maxoc* Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 27/37] lightnvm: normalize geometry nomenclature Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 28/37] lightnvm: add support for 2.0 address format Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 29/37] lightnvm: make address conversions depend on generic device Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 30/37] lightnvm: implement get log report chunk helpers Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 31/37] lightnvm: pblk: check for supported version Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 32/37] lightnvm: pblk: rename ppaf* to addrf* Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 33/37] lightnvm: pblk: implement get log report chunk Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 34/37] lightnvm: pblk: implement 2.0 support Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 35/37] lightnvm: pblk: don't recover unwritten lines Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 36/37] lightnvm: pblk: remove some unnecessary NULL checks Matias Bjørling
2018-03-29 22:05 ` [GIT PULL 37/37] lightnvm: remove function name in strings Matias Bjørling
2018-03-29 23:30 ` [GIT PULL 00/37] lightnvm patches for 4.17 Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180329220524.30363-13-mb@lightnvm.io \
    --to=mb@lightnvm.io \
    --cc=axboe@fb.com \
    --cc=javier@cnexlabs.com \
    --cc=jg@lightnvm.io \
    --cc=keith.busch@intel.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®