Received: by 10.213.65.68 with SMTP id h4csp1992470imn; Thu, 29 Mar 2018 15:15:03 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/dYo7dYzUtXwuk6eWzPfPUo85/u2lt8B5Vn0ed6fHmTqDIpaHZ3DbX7b1ZMpzGSfCEd4ER X-Received: by 10.98.211.4 with SMTP id q4mr7893637pfg.0.1522361703746; Thu, 29 Mar 2018 15:15:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522361703; cv=none; d=google.com; s=arc-20160816; b=laDF4b2G+GGltuS7MmLMvEIXhg+7x8jLrKNbXwHHf/snFsSxEytxlsUfB1ouqPP1gB TMj2WSQeuFdiC/cJ6sRlg3KFTn9te/jg0L6fengsUd3g1VSm/p3IoiPn1Rf+VTPN6Dw0 fYyXCHgDMjXTrKBOUeY4k5e9dwFJAxl6gwg6dd9uEgCyqkr1oJOVFzl02/QJdqpswju5 jrnm70yDpVvo9Lsg2i2F6gWcKdorRPKev4FZVX2bu3uPAkwhPKk0pYy0qyCFoQWfvOZT VWwS6c1/fKEw9YWEb6SqwyIg1eBxSGdXrtMCm/zpOYkaCJZLC9lVtWaUbP1323krbCBG 8NVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=aiXdDg3MGCxpsQae6qGa6wR21I7Fd3vGeuoNT8Um314=; b=TfRcEmQtpbgrXpAdthKCNF9ES6Qy1J/RbvHilHjoQbG1fhiicUvsKFchQaQLQoXGP4 8eFlo7E3C3GsVRk6qiirRYyYhvbV8ZYOaEugWctZAdqQ2oy35Be++WPmhtV1HtU/u7Mb ovOqVBfw/F2VLtth1gNVl9dv4f9vcdrv1+r0Ut7G+yQAEFoC3Lc0kdbKGwKFhfGmPu/V QwGu+ENrPQaSy6DcLtYm+xFED68Owj25ygjtkazYXKxkFGtTfCCYhNevdJf8SwOXrrZg 3+kEUmF6oEKZ3KFEN7tKpqpxT7n2BzJTxOfk+dNuWP8gXuu1b0Hnj//GEukLNc70+Mtx +06Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lightnvm-io.20150623.gappssmtp.com header.s=20150623 header.b=JtsBrDQ2; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g6-v6si2384240pll.677.2018.03.29.15.14.50; Thu, 29 Mar 2018 15:15:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@lightnvm-io.20150623.gappssmtp.com header.s=20150623 header.b=JtsBrDQ2; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752538AbeC2WHP (ORCPT + 99 others); Thu, 29 Mar 2018 18:07:15 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:37864 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752230AbeC2WHL (ORCPT ); Thu, 29 Mar 2018 18:07:11 -0400 Received: by mail-lf0-f65.google.com with SMTP id m200-v6so4580597lfm.4 for ; Thu, 29 Mar 2018 15:07:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lightnvm-io.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=aiXdDg3MGCxpsQae6qGa6wR21I7Fd3vGeuoNT8Um314=; b=JtsBrDQ2gFdS6evr40+8ym8Fp+4SOFYFwtHAjzPMZ6aSGLbtCIIp3tKD9gARB+Y4ab AtOtpzOigmzm4zoYFJBLuQP+tkMInClaiQCYrA6J7Xsum3tnNKK/kVFil3IQF8OqP6cd pP31l5ujJ9iIfhfp7VWtoVIZTqsX5M6XPiqYaI1JS28TezEgdaLrNjlpnVJX/ZlOmHja /5+PUwO90jc/+cbM/Op4a0E9C5cgkNMso2KcAmbTj4Zk22eUfuOl4GYPVCqEnemnFdnt Z4c3jD9kpzbHxhhbdB6uzEeYX9xHJY87M7h2vo3hTKA3m67ZRSFEZIDLYbvuyMlHHaag 2K6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=aiXdDg3MGCxpsQae6qGa6wR21I7Fd3vGeuoNT8Um314=; b=KcGOnWy4p4B1Y2Ljl0MrZaTpP/t3Uu9qH3oEUmlmGG+ngKhS7ArUiHzGCxLQ/mFUQt M0xwOinKKBaQ93srNtp+5N9oMyvh+eI7Y21dO0PFX/IwJR6sG9GG6t/zMXdHEpGOOoA2 KT2W1aYuyQdIofFNISuL1dWysUOjlQrlX+W7TJshsFd1UVHliMmLUiTX43DTF6dpyxO4 5YmOK8KIaiW1dIecylcDcBEHBbs648VmfM/ikQkb32RS9DiugGYKrvukyWPbYGSPwaS6 WviwX799Xp87A95tImF6Am1qqxZdF+emBoptLkNORyYRzB/oZxsSa+IxZ/VX0gKD/LpI dBfA== X-Gm-Message-State: AElRT7GEsB1IUxqC4wZAeOj7Qn0hUKKSpiy8OQqMC4s6GGmWI+LKBDPr MJ8u+zKkmfCAQhm3yvqce20B0Q== X-Received: by 10.46.56.6 with SMTP id f6mr6784944lja.4.1522361229441; Thu, 29 Mar 2018 15:07:09 -0700 (PDT) Received: from Macroninja.cnexlabs.com (x1-6-a4-08-f5-18-3c-3a.cpe.webspeed.dk. [188.176.29.198]) by smtp.gmail.com with ESMTPSA id i89-v6sm1365508lfk.12.2018.03.29.15.07.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 29 Mar 2018 15:07:08 -0700 (PDT) From: =?UTF-8?q?Matias=20Bj=C3=B8rling?= To: axboe@fb.com Cc: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, keith.busch@intel.com, javier@cnexlabs.com, =?UTF-8?q?Javier=20Gonz=C3=A1lez?= , =?UTF-8?q?Matias=20Bj=C3=B8rling?= Subject: [GIT PULL 12/37] lightnvm: pblk: refactor bad block identification Date: Fri, 30 Mar 2018 00:04:59 +0200 Message-Id: <20180329220524.30363-13-mb@lightnvm.io> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180329220524.30363-1-mb@lightnvm.io> References: <20180329220524.30363-1-mb@lightnvm.io> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Javier González 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 Signed-off-by: Matias Bjørling --- 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