From patchwork Wed Jan 27 09:36:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matias Bjorling X-Patchwork-Id: 8131621 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 DC0BBBEEE5 for ; Wed, 27 Jan 2016 09:37:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BBA7720212 for ; Wed, 27 Jan 2016 09:37:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5B7E8201F5 for ; Wed, 27 Jan 2016 09:37:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754241AbcA0JhG (ORCPT ); Wed, 27 Jan 2016 04:37:06 -0500 Received: from mail-wm0-f44.google.com ([74.125.82.44]:38585 "EHLO mail-wm0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753978AbcA0JhA (ORCPT ); Wed, 27 Jan 2016 04:37:00 -0500 Received: by mail-wm0-f44.google.com with SMTP id p63so16989539wmp.1 for ; Wed, 27 Jan 2016 01:36:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lightnvm-io.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=reqzHBQQa3eL7iYYO04+BARm3TVFtZ0nMewo6H27Qe4=; b=Ca5hb+xgH65FFEqjibm8J6AF/d1nSqk2ps8AqVuVoysSn8AryZjRFbhrgfUCzJvLlt Kr1AhoDJ3fYkuibDqxtQbWeRtpk29WNy8gw0dnvgedWLpjWaIgc8o4TaOvZrxmrMS7Xf t6sjtFc+dL+Xer8MRMywKRbqi5M3CYyzJa59EP0pPfB5iDK7CMJZu5sR2mgx0Bhr55Cf fNvsIRBydCTnStmlNHBbbFYJTDbZyoUDTE/lFA8/TuNecDCyoPNe4HdmuLd5Odjou2Pf ojZzR9ntV/T/MHExcRSnxW+z9F2QJTdrmIPp+G+bLfxg7JmeHEpfo0HT9+22k/ZRwFB4 lvGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=reqzHBQQa3eL7iYYO04+BARm3TVFtZ0nMewo6H27Qe4=; b=Ctl8EN7+uQQ4jBBoCc6poQq7BwnCbaINQhmwjG2s1bZCbXmhN8x4PJkpSS9RVsmmsu aclmvdupth1HeH9kR0up1u2AdFXaVcyKRcI/0NYwL65v+Yrrb+SpxMi1o3mW3LQfSiAf U587TFFHk/A2nMGPDVjX5fWR3ITBQyt+1UUHY/Y5mLTxyJvf+pE3qGy1n6dMcwkfSluN XmjCJfKSgouqlVsRx3NXw6mMJFiSGPz0WdOQSQ/DME8JK0dgf9Ec9d0Si5aE8nv/pW9t d4PRSF6aZX8S9CRnwDtpC1NlUsURg1zVQ/hQAmf8gFcAKRlHrJWNWOW/aU3OQGUfa7Ps tJjw== X-Gm-Message-State: AG10YOR8jAUhkpk5QVTMOIcbW/sLhym1vClfYDyFUSKRfFv5pOcc3IyGoitsQpW8vmkX+Q== X-Received: by 10.28.179.84 with SMTP id c81mr29810048wmf.30.1453887419159; Wed, 27 Jan 2016 01:36:59 -0800 (PST) Received: from [192.168.1.131] (6164198-cl69.boa.fiberby.dk. [193.106.164.198]) by smtp.googlemail.com with ESMTPSA id x2sm5287378wjf.13.2016.01.27.01.36.57 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 27 Jan 2016 01:36:58 -0800 (PST) Subject: Re: [PATCH v2 1/2] lightnvm: specify target's logical address area To: Wenwei Tao References: <1453811633-3721-1-git-send-email-ww.tao0320@gmail.com> <56A7882A.50108@lightnvm.io> <56A85B20.4030809@lightnvm.io> Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org From: =?UTF-8?Q?Matias_Bj=c3=b8rling?= Message-ID: <56A88FB9.4020106@lightnvm.io> Date: Wed, 27 Jan 2016 10:36:57 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: 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=ham 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 On 01/27/2016 07:06 AM, Wenwei Tao wrote: > Thanks. > > 2016-01-27 13:52 GMT+08:00 Matias Bjørling : >> On 01/27/2016 03:21 AM, Wenwei Tao wrote: >>> >>> Yes, It's a spelling mistake, will correct it in next version. >> >> >> I can fix it in the version I apply. No problem. Hi Wenwei, I've changed it to this. Clean up the variables a bit. Is that ok with you? Thanks unsigned int version[3]; @@ -487,6 +491,10 @@ struct nvmm_type { /* Statistics */ nvmm_lun_info_print_fn *lun_info_print; + + nvmm_get_area_fn *get_area; + nvmm_put_area_fn *put_area; + struct list_head list; }; --- To unsubscribe from this list: send the line "unsubscribe linux-block" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 33224cb..27a59e8 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -470,6 +470,7 @@ static int nvm_core_init(struct nvm_dev *dev) dev->total_pages = dev->total_blocks * dev->pgs_per_blk; INIT_LIST_HEAD(&dev->online_targets); mutex_init(&dev->mlock); + spin_lock_init(&dev->lock); return 0; } diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c index 7fb725b..6e2685d 100644 --- a/drivers/lightnvm/gennvm.c +++ b/drivers/lightnvm/gennvm.c @@ -20,6 +20,63 @@ #include "gennvm.h" +static int gennvm_get_area(struct nvm_dev *dev, sector_t *begin_sect, + sector_t size) +{ + struct gen_nvm *gn = dev->mp; + struct gennvm_area *area, *prev; + int page_size = dev->sec_size * dev->sec_per_pg; + sector_t begin = 0; + sector_t max_sectors = (page_size * dev->total_pages) >> 9; + + if (size > max_sectors) + return -EINVAL; + + area = kmalloc(sizeof(struct gennvm_area), GFP_KERNEL); + if (!area) + return -ENOMEM; + + spin_lock(&dev->lock); + list_for_each_entry(prev, &gn->area_list, list) { + if (begin + size > prev->begin) { + begin = prev->end; + continue; + } + break; + } + + if ((begin + size) > max_sectors) { + spin_unlock(&dev->lock); + kfree(area); + return -EINVAL; + } + + area->begin = *begin_sect = begin; + area->end = begin + size; + list_add(&area->list, &prev->list); + spin_unlock(&dev->lock); + + return 0; +} + +static void gennvm_put_area(struct nvm_dev *dev, sector_t begin) +{ + struct gen_nvm *gn = dev->mp; + struct gennvm_area *area; + + spin_lock(&dev->lock); + list_for_each_entry(area, &gn->area_list, list) { + if (area->begin != begin) + continue; + + list_del(&area->list); + spin_unlock(&dev->lock); + kfree(area); + return; + } + spin_unlock(&dev->lock); +} + static void gennvm_blocks_free(struct nvm_dev *dev) { struct gen_nvm *gn = dev->mp; @@ -230,6 +287,7 @@ static int gennvm_register(struct nvm_dev *dev) gn->dev = dev; gn->nr_luns = dev->nr_luns; + INIT_LIST_HEAD(&gn->area_list); dev->mp = gn; ret = gennvm_luns_init(dev, gn); @@ -466,6 +524,10 @@ static struct nvmm_type gennvm = { .get_lun = gennvm_get_lun, .lun_info_print = gennvm_lun_info_print, + + .get_area = gennvm_get_area, + .put_area = gennvm_put_area, + }; static int __init gennvm_module_init(void) diff --git a/drivers/lightnvm/gennvm.h b/drivers/lightnvm/gennvm.h index 9c24b5b..04d7c23 100644 --- a/drivers/lightnvm/gennvm.h +++ b/drivers/lightnvm/gennvm.h @@ -39,8 +39,14 @@ struct gen_nvm { int nr_luns; struct gen_lun *luns; + struct list_head area_list; }; +struct gennvm_area { + struct list_head list; + sector_t begin; + sector_t end; /* end is excluded */ +}; #define gennvm_for_each_lun(bm, lun, i) \ for ((i) = 0, lun = &(bm)->luns[0]; \ (i) < (bm)->nr_luns; (i)++, lun = &(bm)->luns[(i)]) diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c index e2710da..20afe1c 100644 --- a/drivers/lightnvm/rrpc.c +++ b/drivers/lightnvm/rrpc.c @@ -1039,7 +1039,11 @@ static int rrpc_map_init(struct rrpc *rrpc) { struct nvm_dev *dev = rrpc->dev; sector_t i; - int ret; + u64 slba; + int ret, page_size; + + page_size = dev->sec_per_pg * dev->sec_size; + slba = rrpc->soffset >> (ilog2(page_size) - 9); rrpc->trans_map = vzalloc(sizeof(struct rrpc_addr) * rrpc->nr_pages); if (!rrpc->trans_map) @@ -1062,8 +1066,8 @@ static int rrpc_map_init(struct rrpc *rrpc) return 0; /* Bring up the mapping table from device */ - ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_pages, - rrpc_l2p_update, rrpc); + ret = dev->ops->get_l2p_tbl(dev, slba, rrpc->nr_pages, rrpc_l2p_update, + rrpc); if (ret) { pr_err("nvm: rrpc: could not read L2P table.\n"); return -EINVAL; @@ -1072,7 +1076,6 @@ static int rrpc_map_init(struct rrpc *rrpc) return 0; } - /* Minimum pages needed within a lun */ #define PAGE_POOL_SIZE 16 #define ADDR_POOL_SIZE 64 @@ -1186,12 +1189,32 @@ err: return -ENOMEM; } +/* returns 0 on success and stores the beginning address in *begin */ +static int rrpc_area_init(struct rrpc *rrpc, sector_t *begin) +{ + struct nvm_dev *dev = rrpc->dev; + struct nvmm_type *mt = dev->mt; + sector_t size = rrpc->nr_luns * dev->sec_per_lun * dev->sec_size; + + size >>= 9; + return mt->get_area(dev, begin, size); +} + +static void rrpc_area_free(struct rrpc *rrpc) +{ + struct nvm_dev *dev = rrpc->dev; + struct nvmm_type *mt = dev->mt; + + mt->put_area(dev, rrpc->soffset); +} + static void rrpc_free(struct rrpc *rrpc) { rrpc_gc_free(rrpc); rrpc_map_free(rrpc); rrpc_core_free(rrpc); rrpc_luns_free(rrpc); + rrpc_area_free(rrpc); kfree(rrpc); } @@ -1312,6 +1335,7 @@ static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk, struct request_queue *bqueue = dev->q; struct request_queue *tqueue = tdisk->queue; struct rrpc *rrpc; + sector_t soffset; int ret; if (!(dev->identity.dom & NVM_RSP_L2P)) { @@ -1337,6 +1361,13 @@ static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk, /* simple round-robin strategy */ atomic_set(&rrpc->next_lun, -1); + ret = rrpc_area_init(rrpc, &soffset); + if (ret < 0) { + pr_err("nvm: rrpc: could not initialize area\n"); + return ERR_PTR(ret); + } + rrpc->soffset = soffset; + ret = rrpc_luns_init(rrpc, lun_begin, lun_end); if (ret) { pr_err("nvm: rrpc: could not initialize luns\n"); diff --git a/drivers/lightnvm/rrpc.h b/drivers/lightnvm/rrpc.h index ef13ac7..9380c68 100644 --- a/drivers/lightnvm/rrpc.h +++ b/drivers/lightnvm/rrpc.h @@ -97,6 +97,7 @@ struct rrpc { struct nvm_dev *dev; struct gendisk *disk; + sector_t soffset; /* logical sector offset */ u64 poffset; /* physical page offset */ int lun_offset; diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index d675011..18f1bb0 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h @@ -351,6 +351,7 @@ struct nvm_dev { char name[DISK_NAME_LEN]; struct mutex mlock; + spinlock_t lock; }; static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev, @@ -463,6 +464,9 @@ typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *, typedef struct nvm_lun *(nvmm_get_lun_fn)(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); +typedef void (nvmm_put_area_fn)(struct nvm_dev *, sector_t); + struct nvmm_type { const char *name;