From patchwork Thu Feb 4 11:34:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenwei Tao X-Patchwork-Id: 8220021 Return-Path: X-Original-To: patchwork-linux-block@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6924D9F3CD for ; Thu, 4 Feb 2016 11:37:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6176720390 for ; Thu, 4 Feb 2016 11:37:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 33EF4200ED for ; Thu, 4 Feb 2016 11:37:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758174AbcBDLgI (ORCPT ); Thu, 4 Feb 2016 06:36:08 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:33767 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758160AbcBDLgE (ORCPT ); Thu, 4 Feb 2016 06:36:04 -0500 Received: by mail-pf0-f193.google.com with SMTP id c10so2822219pfc.0; Thu, 04 Feb 2016 03:36:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kVR1HWEOLb935chtOxeIa1kfOvXAfnvW0QH8Cp/1iV0=; b=GOmXf41Ihe3rlG33Ur9Vy/fNLVh53ZHcuD6hViaLYPOci7f/kmPWpDu93AvqTg0KPg 1D0/jBk0lPoxGc3kFNKdeOTajeSnRh7p9DA12mKOaYY13qrNUii/1b3Y2u0Z1WtF5ubF QU1WmJmMreRDh4HA7enwbrHr2nNZmiXhXPg2QMkbkTvNHMYGznnjpQ5d0sjy8SPV4mqh LKCnlm8Kcu+CJwwBbGfTlemspJVmUh1+sTR++ZOISUlLskjF1SEl7zc/e4c45TzPiPBb w9Tg/3wODE4fbebrVWk+L2K8YklpgIXfJUlPyPs+zm+XMYX0c2RJGTvvrKk8eusZLXIH Z+sw== 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; bh=kVR1HWEOLb935chtOxeIa1kfOvXAfnvW0QH8Cp/1iV0=; b=cpWJjZ9nKaizTWlSFWt6Y6y84wpv8PLmmI5HenT8/HAHbxzIxRQ3h4P9S2Ym09OsWl V2EhtZKDcM8wGAtJohA7WwNlMytbggickApqAayRJd/Jh92VTbZ11E8sXYdLl8XOqnnu b3fBXE+UZqOpJszkyTAt7UIuB2QMUvYud0iZsITaacdhLWx9Z0jMVitxTrkdF8w4fJZ4 gwtiUulcOUfHlM/L4airQY+Mb9/WetzUxh1syZWmjYCa16UarQtigchc2y3cdTA41HNj L5DM4e9IGtN0vzl3Gc8PNAxITQMC8R1ocZly+mJ0c9vPsnmZr/dgMHBpLlvDR34kCscE 22/A== X-Gm-Message-State: AG10YORXFPpXLF1golLSQJ4vAzwKP0aAA/w4fg/4p7zS7L3NoRyayOzSCaNHiEKbj8+pMw== X-Received: by 10.98.69.155 with SMTP id n27mr10201931pfi.68.1454585764267; Thu, 04 Feb 2016 03:36:04 -0800 (PST) Received: from localhost.localdomain ([2002:6fc4:c08a::6fc4:c08a]) by smtp.gmail.com with ESMTPSA id cf6sm16474990pad.41.2016.02.04.03.36.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 04 Feb 2016 03:36:03 -0800 (PST) From: Wenwei Tao To: mb@lightnvm.io Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 2/3] lightnvm: add a bitmap of luns Date: Thu, 4 Feb 2016 19:34:46 +0800 Message-Id: <1454585687-4720-2-git-send-email-ww.tao0320@gmail.com> X-Mailer: git-send-email 2.5.1.windows.1 In-Reply-To: <1454585687-4720-1-git-send-email-ww.tao0320@gmail.com> References: <1454585687-4720-1-git-send-email-ww.tao0320@gmail.com> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, 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 Add a bitmap of luns to indicate the status of luns: inuse/available. When create targets do the necessary check to avoid allocating luns that are already allocated. Signed-off-by: Wenwei Tao --- drivers/lightnvm/core.c | 5 ++++ drivers/lightnvm/gennvm.c | 18 +++++++++++++++ drivers/lightnvm/rrpc.c | 59 +++++++++++++++++++++++++++++++++++------------ include/linux/lightnvm.h | 5 ++++ 4 files changed, 72 insertions(+), 15 deletions(-) diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 93c035b..11b8e2d 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -464,6 +464,10 @@ static int nvm_core_init(struct nvm_dev *dev) dev->nr_luns = dev->luns_per_chnl * dev->nr_chnls; dev->total_secs = dev->nr_luns * dev->sec_per_lun; + dev->lun_map = kcalloc(BITS_TO_LONGS(dev->nr_luns), + sizeof(unsigned long), GFP_KERNEL); + if (!dev->lun_map) + return -ENOMEM; INIT_LIST_HEAD(&dev->online_targets); mutex_init(&dev->mlock); spin_lock_init(&dev->lock); @@ -606,6 +610,7 @@ void nvm_unregister(char *disk_name) up_write(&nvm_lock); nvm_exit(dev); + kfree(dev->lun_map); kfree(dev); } EXPORT_SYMBOL(nvm_unregister); diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c index fba3fbd..adc10c2 100644 --- a/drivers/lightnvm/gennvm.c +++ b/drivers/lightnvm/gennvm.c @@ -190,6 +190,9 @@ static int gennvm_block_map(u64 slba, u32 nlb, __le64 *entries, void *private) lun_id = div_u64(pba, dev->sec_per_lun); lun = &gn->luns[lun_id]; + if (!test_bit(lun_id, dev->lun_map)) + __set_bit(lun_id, dev->lun_map); + /* Calculate block offset into lun */ pba = pba - (dev->sec_per_lun * lun_id); blk = &lun->vlun.blocks[div_u64(pba, dev->sec_per_blk)]; @@ -480,10 +483,23 @@ static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk, return nvm_erase_ppa(dev, &addr, 1); } +static int gennvm_reserve_lun(struct nvm_dev *dev, int lunid) +{ + return test_and_set_bit(lunid, dev->lun_map); +} + +static void gennvm_release_lun(struct nvm_dev *dev, int lunid) +{ + WARN_ON(!test_and_clear_bit(lunid, dev->lun_map)); +} + static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid) { struct gen_nvm *gn = dev->mp; + if (unlikely(lunid >= dev->nr_luns)) + return NULL; + return &gn->luns[lunid].vlun; } @@ -525,6 +541,8 @@ static struct nvmm_type gennvm = { .erase_blk = gennvm_erase_blk, .get_lun = gennvm_get_lun, + .reserve_lun = gennvm_reserve_lun, + .release_lun = gennvm_release_lun, .lun_info_print = gennvm_lun_info_print, .get_area = gennvm_get_area, diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c index 6ce5f73..2bd5789 100644 --- a/drivers/lightnvm/rrpc.c +++ b/drivers/lightnvm/rrpc.c @@ -1128,6 +1128,22 @@ static void rrpc_core_free(struct rrpc *rrpc) static void rrpc_luns_free(struct rrpc *rrpc) { + struct nvm_dev *dev = rrpc->dev; + struct nvm_lun *lun; + struct rrpc_lun *rlun; + int i; + + if (!rrpc->luns) + return; + + for (i = 0; i < rrpc->nr_luns; i++) { + rlun = &rrpc->luns[i]; + lun = rlun->parent; + if (!lun) + break; + dev->mt->release_lun(dev, lun->id); + vfree(rlun->blocks); + } kfree(rrpc->luns); } @@ -1135,7 +1151,7 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) { struct nvm_dev *dev = rrpc->dev; struct rrpc_lun *rlun; - int i, j; + int i, j, ret = -EINVAL; if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) { pr_err("rrpc: number of pages per block too high."); @@ -1151,25 +1167,26 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) /* 1:1 mapping */ for (i = 0; i < rrpc->nr_luns; i++) { - struct nvm_lun *lun = dev->mt->get_lun(dev, lun_begin + i); + int lunid = lun_begin + i; + struct nvm_lun *lun; - rlun = &rrpc->luns[i]; - rlun->rrpc = rrpc; - rlun->parent = lun; - INIT_LIST_HEAD(&rlun->prio_list); - INIT_LIST_HEAD(&rlun->open_list); - INIT_LIST_HEAD(&rlun->closed_list); - - INIT_WORK(&rlun->ws_gc, rrpc_lun_gc); - spin_lock_init(&rlun->lock); + if (dev->mt->reserve_lun(dev, lunid)) { + pr_err("rrpc: lun %u is already allocated\n", lunid); + goto err; + } - rrpc->total_blocks += dev->blks_per_lun; - rrpc->nr_sects += dev->sec_per_lun; + lun = dev->mt->get_lun(dev, lunid); + if (!lun) + goto err; + rlun = &rrpc->luns[i]; + rlun->parent = lun; rlun->blocks = vzalloc(sizeof(struct rrpc_block) * rrpc->dev->blks_per_lun); - if (!rlun->blocks) + if (!rlun->blocks) { + ret = -ENOMEM; goto err; + } for (j = 0; j < rrpc->dev->blks_per_lun; j++) { struct rrpc_block *rblk = &rlun->blocks[j]; @@ -1180,11 +1197,23 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) INIT_LIST_HEAD(&rblk->prio); spin_lock_init(&rblk->lock); } + + rlun->rrpc = rrpc; + INIT_LIST_HEAD(&rlun->prio_list); + INIT_LIST_HEAD(&rlun->open_list); + INIT_LIST_HEAD(&rlun->closed_list); + + INIT_WORK(&rlun->ws_gc, rrpc_lun_gc); + spin_lock_init(&rlun->lock); + + rrpc->total_blocks += dev->blks_per_lun; + rrpc->nr_sects += dev->sec_per_lun; + } return 0; err: - return -ENOMEM; + return ret; } /* returns 0 on success and stores the beginning address in *begin */ diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index ce58ad5..2a17dc1 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h @@ -342,6 +342,7 @@ struct nvm_dev { int nr_luns; unsigned max_pages_per_blk; + unsigned long *lun_map; void *ppalist_pool; struct nvm_id identity; @@ -462,6 +463,8 @@ typedef int (nvmm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *); typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *, unsigned long); typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int); +typedef int (nvmm_reserve_lun)(struct nvm_dev *, int); +typedef void (nvmm_release_lun)(struct nvm_dev *, int); typedef void (nvmm_lun_info_print_fn)(struct nvm_dev *); typedef int (nvmm_get_area_fn)(struct nvm_dev *, sector_t *, sector_t); @@ -488,6 +491,8 @@ struct nvmm_type { /* Configuration management */ nvmm_get_lun_fn *get_lun; + nvmm_reserve_lun *reserve_lun; + nvmm_release_lun *release_lun; /* Statistics */ nvmm_lun_info_print_fn *lun_info_print;