From patchwork Wed Feb 17 11:00:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?UTF-8?q?Javier=20Gonz=C3=A1lez?= X-Patchwork-Id: 8336671 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 32DB0C02AA for ; Wed, 17 Feb 2016 11:00:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E44D920381 for ; Wed, 17 Feb 2016 11:00:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8530920376 for ; Wed, 17 Feb 2016 11:00:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934159AbcBQLAS (ORCPT ); Wed, 17 Feb 2016 06:00:18 -0500 Received: from mail-wm0-f49.google.com ([74.125.82.49]:32948 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934154AbcBQLAP (ORCPT ); Wed, 17 Feb 2016 06:00:15 -0500 Received: by mail-wm0-f49.google.com with SMTP id g62so231736843wme.0 for ; Wed, 17 Feb 2016 03:00:14 -0800 (PST) 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:mime-version:content-type :content-transfer-encoding; bh=wzpXq3A4mdh8f88ZixDPvy2c1zljAbwgdy3b+yUTHFA=; b=UyJHSFdxqoE4P4F7ZOby323ig6JERvkokRiWzn614m1EDF9EdY8k+GajXJXV/B02bq WDufTRV0WH+XLpKogtPsmL7TERKpHeWTS0k8GqQhR2KsNiaR8i8cis/DStcAmYp6kXa7 Ee1mWML1jjXm52pVmn9vW6AqDoaAA2OAp3ryPQSugfOjTikGIP8cAwfzOhk9N3z7U3hH vZ+w1K1zQbvAR0wjvoULcGGwlFvYJpVnCMfahW1SQj0qGyALcLU4K6n01YBX3WHjCaUH hicZSKNuukshZuBqWmNdI11rzmw9I83iuSujkm2jLY13PHJTq6Xq7Ncltt/p3W8y2rpF nYbw== 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:mime-version :content-type:content-transfer-encoding; bh=wzpXq3A4mdh8f88ZixDPvy2c1zljAbwgdy3b+yUTHFA=; b=VJ2wXFscd4IuTZQQcxok+WAEAiAUbeD/W7nTncpFuKwm3pdyCvllNduGYT8imgt55k PKRpZaSNZodDx0DXQbcHkxvUV1eLtr1X32obL8ykyJTb0fD4yeIOy6vmDHBxrhMJBi/A IBRsCOKctX+pD2QMhJSzXsVdaLmA2497weF2a7Qb8NjDNleOj92yvr6zqfmkSrx2i0dN LpnWBhPmJ937khcaebobDpGK+Y3zlgIARzXycpKQXkNzC5CH/94K9iVxpuiDQNot5U7Q FCmgQ+650noXcVeoaLmohBVMuRU9JWT6rwtjfZkx8GihrISbOlfQSViMJyXxiyWRSbW0 2yUQ== X-Gm-Message-State: AG10YOQ4PI0HhJg+QT3ADnSsMSU8LogVtCzdPQN85ItTFa2OF8oXQy/DyPHC87bhQAfXiQ== X-Received: by 10.28.226.6 with SMTP id z6mr2788434wmg.44.1455706814029; Wed, 17 Feb 2016 03:00:14 -0800 (PST) Received: from localhost.localdomain (6164198-cl69.boa.fiberby.dk. [193.106.164.198]) by smtp.gmail.com with ESMTPSA id ei9sm885326wjd.40.2016.02.17.03.00.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 17 Feb 2016 03:00:13 -0800 (PST) From: "=?UTF-8?q?Javier=20Gonz=C3=A1lez?=" X-Google-Original-From: =?UTF-8?q?Javier=20Gonz=C3=A1lez?= To: mb@lightnvm.io Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, =?UTF-8?q?Javier=20Gonz=C3=A1lez?= Subject: [PATCH] lightnvm: generalize rrpc ppa calculations Date: Wed, 17 Feb 2016 12:00:07 +0100 Message-Id: <1455706807-29375-1-git-send-email-javier@javigon.com> X-Mailer: git-send-email 2.1.4 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=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 In rrpc, some calculations assume a certain configuration (e.g., 1 LUN, 1 sector per page). The reason behind this was that we have used a simple configuration in QEMU to test core features generally in LightNVM, and concretely in rrpc. This patch relaxes these assumptions and generalizes calculations in order to support real hardware. Note that more complex configurations in QEMU, that allow to simulate this hardware, are also pushed into the qemu-nvme repository implementing LightNVM support, available under the Open-Channel SSD project in github [1]. [1] https://github.com/OpenChannelSSD/qemu-nvme Signed-off-by: Javier González --- drivers/lightnvm/rrpc.c | 45 ++++++++++++++++++++++++++++----------------- drivers/lightnvm/rrpc.h | 9 +++++++++ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c index 775bf6c2..f366c78 100644 --- a/drivers/lightnvm/rrpc.c +++ b/drivers/lightnvm/rrpc.c @@ -38,7 +38,7 @@ static void rrpc_page_invalidate(struct rrpc *rrpc, struct rrpc_addr *a) spin_lock(&rblk->lock); - div_u64_rem(a->addr, rrpc->dev->pgs_per_blk, &pg_offset); + div_u64_rem(a->addr, rrpc->dev->sec_per_blk, &pg_offset); WARN_ON(test_and_set_bit(pg_offset, rblk->invalid_pages)); rblk->nr_invalid_pages++; @@ -113,14 +113,24 @@ static void rrpc_discard(struct rrpc *rrpc, struct bio *bio) static int block_is_full(struct rrpc *rrpc, struct rrpc_block *rblk) { - return (rblk->next_page == rrpc->dev->pgs_per_blk); + return (rblk->next_page == rrpc->dev->sec_per_blk); } +/* Calculate relative addr for the given block, considering instantiated LUNs */ +static u64 block_to_rel_addr(struct rrpc *rrpc, struct rrpc_block *rblk) +{ + struct nvm_block *blk = rblk->parent; + int lun_blk = blk->id % (rrpc->dev->blks_per_lun * rrpc->nr_luns); + + return lun_blk * rrpc->dev->sec_per_blk; +} + +/* Calculate global addr for the given block */ static u64 block_to_addr(struct rrpc *rrpc, struct rrpc_block *rblk) { struct nvm_block *blk = rblk->parent; - return blk->id * rrpc->dev->pgs_per_blk; + return blk->id * rrpc->dev->sec_per_blk; } static struct ppa_addr linear_to_generic_addr(struct nvm_dev *dev, @@ -136,7 +146,7 @@ static struct ppa_addr linear_to_generic_addr(struct nvm_dev *dev, l.g.sec = secs; sector_div(ppa, dev->sec_per_pg); - div_u64_rem(ppa, dev->sec_per_blk, &pgs); + div_u64_rem(ppa, dev->pgs_per_blk, &pgs); l.g.pg = pgs; sector_div(ppa, dev->pgs_per_blk); @@ -191,12 +201,12 @@ static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun, return NULL; } - rblk = &rlun->blocks[blk->id]; + rblk = rrpc_get_rblk(rlun, blk->id); list_add_tail(&rblk->list, &rlun->open_list); spin_unlock(&lun->lock); blk->priv = rblk; - bitmap_zero(rblk->invalid_pages, rrpc->dev->pgs_per_blk); + bitmap_zero(rblk->invalid_pages, rrpc->dev->sec_per_blk); rblk->next_page = 0; rblk->nr_invalid_pages = 0; atomic_set(&rblk->data_cmnt_size, 0); @@ -286,11 +296,11 @@ static int rrpc_move_valid_pages(struct rrpc *rrpc, struct rrpc_block *rblk) struct bio *bio; struct page *page; int slot; - int nr_pgs_per_blk = rrpc->dev->pgs_per_blk; + int nr_sec_per_blk = rrpc->dev->sec_per_blk; u64 phys_addr; DECLARE_COMPLETION_ONSTACK(wait); - if (bitmap_full(rblk->invalid_pages, nr_pgs_per_blk)) + if (bitmap_full(rblk->invalid_pages, nr_sec_per_blk)) return 0; bio = bio_alloc(GFP_NOIO, 1); @@ -306,10 +316,10 @@ static int rrpc_move_valid_pages(struct rrpc *rrpc, struct rrpc_block *rblk) } while ((slot = find_first_zero_bit(rblk->invalid_pages, - nr_pgs_per_blk)) < nr_pgs_per_blk) { + nr_sec_per_blk)) < nr_sec_per_blk) { /* Lock laddr */ - phys_addr = (rblk->parent->id * nr_pgs_per_blk) + slot; + phys_addr = rblk->parent->id * nr_sec_per_blk + slot; try: spin_lock(&rrpc->rev_lock); @@ -381,7 +391,7 @@ finished: mempool_free(page, rrpc->page_pool); bio_put(bio); - if (!bitmap_full(rblk->invalid_pages, nr_pgs_per_blk)) { + if (!bitmap_full(rblk->invalid_pages, nr_sec_per_blk)) { pr_err("nvm: failed to garbage collect block\n"); return -EIO; } @@ -677,7 +687,7 @@ static void rrpc_end_io_write(struct rrpc *rrpc, struct rrpc_rq *rrqd, lun = rblk->parent->lun; cmnt_size = atomic_inc_return(&rblk->data_cmnt_size); - if (unlikely(cmnt_size == rrpc->dev->pgs_per_blk)) + if (unlikely(cmnt_size == rrpc->dev->sec_per_blk)) rrpc_run_gc(rrpc, rblk); } } @@ -1030,7 +1040,7 @@ static int rrpc_l2p_update(u64 slba, u32 nlb, __le64 *entries, void *private) continue; addr[i].addr = pba; - raddr[pba].addr = slba + i; + raddr[pba % rrpc->nr_sects].addr = slba + i; } return 0; @@ -1137,7 +1147,7 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) struct rrpc_lun *rlun; int i, j; - if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) { + if (dev->sec_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) { pr_err("rrpc: number of pages per block too high."); return -EINVAL; } @@ -1238,10 +1248,11 @@ static void rrpc_block_map_update(struct rrpc *rrpc, struct rrpc_block *rblk) struct nvm_dev *dev = rrpc->dev; int offset; struct rrpc_addr *laddr; - u64 paddr, pladdr; + u64 bpaddr, paddr, pladdr; - for (offset = 0; offset < dev->pgs_per_blk; offset++) { - paddr = block_to_addr(rrpc, rblk) + offset; + bpaddr = block_to_rel_addr(rrpc, rblk); + for (offset = 0; offset < dev->sec_per_blk; offset++) { + paddr = bpaddr + offset; pladdr = rrpc->rev_trans_map[paddr].addr; if (pladdr == ADDR_EMPTY) diff --git a/drivers/lightnvm/rrpc.h b/drivers/lightnvm/rrpc.h index 3989d65..855f4a5 100644 --- a/drivers/lightnvm/rrpc.h +++ b/drivers/lightnvm/rrpc.h @@ -156,6 +156,15 @@ struct rrpc_rev_addr { u64 addr; }; +static inline struct rrpc_block *rrpc_get_rblk(struct rrpc_lun *rlun, + int blk_id) +{ + struct rrpc *rrpc = rlun->rrpc; + int lun_blk = blk_id % rrpc->dev->blks_per_lun; + + return &rlun->blocks[lun_blk]; +} + static inline sector_t rrpc_get_laddr(struct bio *bio) { return bio->bi_iter.bi_sector / NR_PHY_IN_LOG;