From patchwork Thu Mar 29 22:04:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matias Bjorling X-Patchwork-Id: 10316571 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6CAE960353 for ; Thu, 29 Mar 2018 22:14:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 539002A534 for ; Thu, 29 Mar 2018 22:14:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 487B92A539; Thu, 29 Mar 2018 22:14:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8A4E82A534 for ; Thu, 29 Mar 2018 22:13:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752510AbeC2WHN (ORCPT ); Thu, 29 Mar 2018 18:07:13 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:38380 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752259AbeC2WHL (ORCPT ); Thu, 29 Mar 2018 18:07:11 -0400 Received: by mail-lf0-f65.google.com with SMTP id u3-v6so10329378lff.5 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=jelDWy0RXuJUimJOc9xgDB1DZvbVQokwpTwAQabwwLCkuNVB+DJKQ0OVYoCcfgmHYv t0l6eB7tq8WVHqKe+fajcmEdcopAbVOq2FvOTzj5KJ3/C2VYmMaoFRk18uch1DnkuQO3 +qRXMo8rW6cQGIyhyLYKjUcEkujB9fNx6XwkqXA+CfWwNLIUXSQz8RLrjtHiHyuQRMfO XVpvgOBBXp5VAoobxhQKdpy0vs9zSxVM5cMJflnhI9O4YndeBVeAIKk96KAiP1hSwHh4 Dl5iEl0tWgNB2DR2ckf7D5xSnOTtiC5ZRyyGQNcspN/luCcfPb8ZuA9ed2AvLmAbMGtP hDvw== X-Gm-Message-State: AElRT7Fj385GF2stQMZ6fhp9u1LsRAhgSOcFaRmHBKPJi8UMl5XR3Fgm MPZXkE4EKgkbgw0A6DY+pTgOSg== X-Google-Smtp-Source: AIpwx4/LeuIKv+LrrU3jPFuPJHyckVJBwsYyhywjOGQBYEm2hF96q5nPIkPQLIoGe05uccamr6QLXA== 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 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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; };