From patchwork Fri Feb 19 12:56:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Matias_Bj=C3=B8rling?= X-Patchwork-Id: 8360631 Return-Path: X-Original-To: patchwork-linux-block@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A610AC0553 for ; Fri, 19 Feb 2016 12:58:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AD25120494 for ; Fri, 19 Feb 2016 12:58:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8FAEF204A2 for ; Fri, 19 Feb 2016 12:58:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161980AbcBSM55 (ORCPT ); Fri, 19 Feb 2016 07:57:57 -0500 Received: from mail-wm0-f41.google.com ([74.125.82.41]:37395 "EHLO mail-wm0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757853AbcBSM5x (ORCPT ); Fri, 19 Feb 2016 07:57:53 -0500 Received: by mail-wm0-f41.google.com with SMTP id g62so69783000wme.0 for ; Fri, 19 Feb 2016 04:57:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bjorling.me; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=8CFpnd4YxEfIxqXCFdtdxLpUcI0OVLVm/JoZfgGd5BY=; b=qTSFOwWD6FIirFFHggA90P/LRY0uBgIqU2Gx0LargMgqRH0bAlDOPG2YCL0EcB0yPQ 7nCLR2BJlItUAUsl/ZLHDg4XuLZTfJWulKf7R/CxIoY/sr1MVauQRYZHsG9BsViCoWGK hrKtqjJaznfaLz6zi/cnqYZ/bonLlbf+gobCs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=8CFpnd4YxEfIxqXCFdtdxLpUcI0OVLVm/JoZfgGd5BY=; b=Rt43/gcs0X5gTHsOLECrYp/OLOqTToeGCE3ZpqLqqDj2JyuLOjwlRezgT9nAtifckG MlAvaW5K0ix+L2l4uci4wEnVrEGwlCg2jPdwpsxqC/JhZ3C4VvN8sgITNjxei/EteVf0 5bdvBss7dGAAU4fRpyXK64lUBmht2Gm5aHUSz2Db3vSHx4AHGlF0Z37S1KdFCzAjhaCs Gb0eIfCKJAGEfsGDvQ5/tWGS2pWxK/90gTQT+qE3Hn2dZ23XmfcUF4iplCAZpp23sN9n 9MPKIxrMP7IvCk7KA2ct7R8jbWMCRTGVr98C9/kA4c/d3MK98d3gDMGPVtMT55U0QdBO a2yQ== X-Gm-Message-State: AG10YOQQyCy6rCY3lI4XMVc+K07I3BuJiUlAxR4e/2ZPi6FROh/u50D0K6x4nTVHwLfIoA== X-Received: by 10.28.130.205 with SMTP id e196mr9361313wmd.34.1455886672668; Fri, 19 Feb 2016 04:57:52 -0800 (PST) Received: from localhost.localdomain (6164198-cl69.boa.fiberby.dk. [193.106.164.198]) by smtp.gmail.com with ESMTPSA id ks5sm11157902wjb.13.2016.02.19.04.57.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 19 Feb 2016 04:57:52 -0800 (PST) From: =?UTF-8?q?Matias=20Bj=C3=B8rling?= To: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, axboe@fb.com Cc: =?UTF-8?q?Matias=20Bj=C3=B8rling?= Subject: [PATCH 2/3] lightnvm: fold get bb tbl when using dual/quad plane mode Date: Fri, 19 Feb 2016 13:56:58 +0100 Message-Id: <1455886619-3007-3-git-send-email-m@bjorling.me> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455886619-3007-1-git-send-email-m@bjorling.me> References: <1455886619-3007-1-git-send-email-m@bjorling.me> MIME-Version: 1.0 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When the media manager runs in dual or quad plane mode, lightnvm abstracts away plane specific commands. This poses a problem for get bad block table, as it reports bad blocks per plane, making the table either two or four times bigger than expected. Fold the bad block list before returning. Signed-off-by: Matias Bjørling --- drivers/lightnvm/core.c | 2 +- drivers/nvme/host/lightnvm.c | 46 +++++++++++++++++++++++++++++++++++++++----- include/linux/lightnvm.h | 6 +++--- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index b53632d..0d1fb6b 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -250,7 +250,7 @@ int nvm_set_rqd_ppalist(struct nvm_dev *dev, struct nvm_rq *rqd, return 0; } - plane_cnt = (1 << dev->plane_mode); + plane_cnt = dev->plane_mode; rqd->nr_pages = plane_cnt * nr_ppas; if (dev->ops->max_phys_sect < rqd->nr_pages) diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c index 55dab93..513a59c 100644 --- a/drivers/nvme/host/lightnvm.c +++ b/drivers/nvme/host/lightnvm.c @@ -379,8 +379,31 @@ out: return ret; } +static void nvme_nvm_bb_tbl_fold(struct nvm_dev *nvmdev, + int nr_dst_blks, u8 *dst_blks, + int nr_src_blks, u8 *src_blks) +{ + int blk, offset, pl, blktype; + + for (blk = 0; blk < nr_dst_blks; blk++) { + offset = blk * nvmdev->plane_mode; + blktype = src_blks[offset]; + + /* Bad blocks on any planes take precedence over other types */ + for (pl = 0; pl < nvmdev->plane_mode; pl++) { + if (src_blks[offset + pl] & + (NVM_BLK_T_BAD|NVM_BLK_T_GRWN_BAD)) { + blktype = src_blks[offset + pl]; + break; + } + } + + dst_blks[blk] = blktype; + } +} + static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa, - int nr_blocks, nvm_bb_update_fn *update_bbtbl, + int nr_dst_blks, nvm_bb_update_fn *update_bbtbl, void *priv) { struct request_queue *q = nvmdev->q; @@ -388,7 +411,9 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa, struct nvme_ctrl *ctrl = ns->ctrl; struct nvme_nvm_command c = {}; struct nvme_nvm_bb_tbl *bb_tbl; - int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_blocks; + u8 *dst_blks = NULL; + int nr_src_blks = nr_dst_blks * nvmdev->plane_mode; + int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_src_blks; int ret = 0; c.get_bb.opcode = nvme_nvm_admin_get_bb_tbl; @@ -399,6 +424,12 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa, if (!bb_tbl) return -ENOMEM; + dst_blks = kzalloc(nr_dst_blks, GFP_KERNEL); + if (!dst_blks) { + ret = -ENOMEM; + goto out; + } + ret = nvme_submit_sync_cmd(ctrl->admin_q, (struct nvme_command *)&c, bb_tbl, tblsz); if (ret) { @@ -420,16 +451,21 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa, goto out; } - if (le32_to_cpu(bb_tbl->tblks) != nr_blocks) { + if (le32_to_cpu(bb_tbl->tblks) != nr_src_blks) { ret = -EINVAL; dev_err(ctrl->dev, "bbt unsuspected blocks returned (%u!=%u)", - le32_to_cpu(bb_tbl->tblks), nr_blocks); + le32_to_cpu(bb_tbl->tblks), nr_src_blks); goto out; } + nvme_nvm_bb_tbl_fold(nvmdev, nr_dst_blks, dst_blks, + nr_src_blks, bb_tbl->blk); + ppa = dev_to_generic_addr(nvmdev, ppa); - ret = update_bbtbl(ppa, nr_blocks, bb_tbl->blk, priv); + ret = update_bbtbl(ppa, nr_dst_blks, dst_blks, priv); + out: + kfree(dst_blks); kfree(bb_tbl); return ret; } diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index 08c1e14..c3c4318 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h @@ -92,9 +92,9 @@ enum { NVM_ADDRMODE_CHANNEL = 1, /* Plane programming mode for LUN */ - NVM_PLANE_SINGLE = 0, - NVM_PLANE_DOUBLE = 1, - NVM_PLANE_QUAD = 2, + NVM_PLANE_SINGLE = 1, + NVM_PLANE_DOUBLE = 2, + NVM_PLANE_QUAD = 4, /* Status codes */ NVM_RSP_SUCCESS = 0x0,