Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2575787imm; Mon, 10 Sep 2018 03:23:05 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbcdMAKuhsJawxa94x6yAMUxJpMrHr/n8DwN55fO5y0coCXgX+ypCiEKsM3hXCRC2w3w8zR X-Received: by 2002:a17:902:6689:: with SMTP id e9-v6mr673056plk.115.1536574984947; Mon, 10 Sep 2018 03:23:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536574984; cv=none; d=google.com; s=arc-20160816; b=F2Fn7H4+8I45/hb6ATlAoFMH/y9TSwwAPIyVrZKm9ja+w/rYE2maZmZ0VuNRUJr4/O kih6JLYAnA+5FWb19o7BZuZv35DtuMK6QyH/r1aOomBw6RprKxSfqRbqUQFqxNeqjvAV fTeg82MzthbKFK0Mjf6C0o4o52p2BIC3XGcgDJTBfQi9SC0sUYiCu7iBzZjo/w9dODdk FlnvtLvSipODmP9shgI3YPByrpjqH18cAX3HPMrU8xEuUyyCaKoFFFn+Ei05c1b7xKoD X9JLnwQZO8y/sDtkwZril+dbP+s3jvswoPb6nC8L6nkIzWuotuPNi5tzlU3aePeK7mJe wyzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=KnXqzmnvMCOnr0geCDo2Grv3jYFwVu7hadrxQNJcEV0=; b=P0N2pQ5LPKCa3wPAo8Of7nn7836oWEU2FNsKooLY+z7xzm1DKFKvDF4SU9ecY9aID3 Mv00REGgVLdYtStetcysCmyibRf+Usd0sy9EGLyAdyRL3O8VkIT1jpdHZ+gQgJakGSmo U4179VONV+xXlE8ZTY7evEy3VK5TzaUEHsDlJhZrDJfiuJA+sujia2MTmsR1t4YkpZi8 fcypfiaIL89bYlKRPqPWEVagsfcCIuZxiTKbp1Kv85m1rGeykfrZaBAb5sognSYneRrw snUcOKTgC02sj4Qjf42q6PHZLOjCIsoyLy0EEiTICInzvllBBOz9WxcQkcuUXdot7A5g 3i9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lightnvm-io.20150623.gappssmtp.com header.s=20150623 header.b=FjmgXLBF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id gn18si16329861plb.500.2018.09.10.03.22.49; Mon, 10 Sep 2018 03:23:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@lightnvm-io.20150623.gappssmtp.com header.s=20150623 header.b=FjmgXLBF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728295AbeIJPO5 (ORCPT + 99 others); Mon, 10 Sep 2018 11:14:57 -0400 Received: from mail-lj1-f193.google.com ([209.85.208.193]:38746 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726738AbeIJPO4 (ORCPT ); Mon, 10 Sep 2018 11:14:56 -0400 Received: by mail-lj1-f193.google.com with SMTP id p6-v6so17423644ljc.5 for ; Mon, 10 Sep 2018 03:21:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lightnvm-io.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=KnXqzmnvMCOnr0geCDo2Grv3jYFwVu7hadrxQNJcEV0=; b=FjmgXLBFT8gCmv/u8PmHRJKAM/x7JRFj3wLVHZmiwFppDVovndqGb7B31vcxGNxuTI qUlJlJ66rl7YFWKWfEe1y5C+vJCxYbpMRrrxhuT879B+j2q5bPb72WM7ArLhxdVj4272 P1dhc0alQhTSDIC4uHLZQqUNMVIDfaxRWfqTYckTvs9kpqmQRB2Alm3WzRXkHU1rPEce iRDhfTaoAGOTamb6+So+niHag/jiWsl7sgk2xVQ1AvZh7bJT6eHLb1aO2aSsAjfdvHTi /yaQbh9iN1SrBXM0jK/p2fdReY1b/jI9gqXvURbEkXdeokj3N+OhCRDJEvXTVx1aX7Kz njHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=KnXqzmnvMCOnr0geCDo2Grv3jYFwVu7hadrxQNJcEV0=; b=IUCZo9FwhfykAoheERxJPCNk9c24bedJKuhusE1hhQds5nJQ8vYJxYEY0bGCcc0Pm9 f+EP25QGYRf/1N/GwXKYeCAV0FtS6pidrDYBYW2YA3ltgHCtymuhAZZL9ywOeSa9Ohiu WCXMvdlMEo9FaRSKObsR3qJE4Gbbi5Aw9+ByXBxDMdvfKzX8ZWUrMqO57NJji84N/9tQ bnecsJ+tXQzjzdJNSzOeI1VkppZ4d62vAX5nHf2lchFZnfNUcNv0pqaWgcCgLvH+4lFY FGGXWenUZYfSBT3HvV64+vKxoi7RzZ8KOdWevBLaSJPBWBeeTuZL3Bkm4md9O7C5C81J nnFQ== X-Gm-Message-State: APzg51DTCGR1D6AfJO5Rly4Twkw/UfWNtj1Pr3WPlzfKQeLYDpdQab9W c/UpshN/D9adJpfVvPxWa9u+DQIqwEA= X-Received: by 2002:a2e:5c07:: with SMTP id q7-v6mr11750649ljb.119.1536574892356; Mon, 10 Sep 2018 03:21:32 -0700 (PDT) Received: from [192.168.0.10] (95-166-82-66-cable.dk.customer.tdc.net. [95.166.82.66]) by smtp.googlemail.com with ESMTPSA id 103-v6sm2652697lfs.28.2018.09.10.03.21.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 10 Sep 2018 03:21:31 -0700 (PDT) Subject: Re: [PATCH 3/3] lightnvm: pblk: support variable OOB size To: javier@javigon.com Cc: igor.j.konopko@intel.com, marcin.dziegielewski@intel.com, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, javier@cnexlabs.com References: <1535537370-10729-1-git-send-email-javier@cnexlabs.com> <1535537370-10729-4-git-send-email-javier@cnexlabs.com> From: =?UTF-8?Q?Matias_Bj=c3=b8rling?= Message-ID: <5298a07e-eecd-4eca-ce0b-a87977d0c298@lightnvm.io> Date: Mon, 10 Sep 2018 12:21:29 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <1535537370-10729-4-git-send-email-javier@cnexlabs.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-GB Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 08/29/2018 12:09 PM, Javier González wrote: > pblk uses 8 bytes in the metadata region area exposed by the device > through the out of band area to store the lba mapped to the given > physical sector. This is used for recovery purposes. Given that the > first generation OCSSD devices exposed 16 bytes, pblk used a hard-coded > structure for this purpose. > > This patch relaxes the 16 bytes assumption and uses the metadata size > reported by the device to layout metadata appropriately for the vector > commands. This adds support for arbitrary metadata sizes, as long as > these are larger than 8 bytes. Note that this patch does not address the > case in which the device does not expose an out of band area and that > pblk creation will fail in this case. > > Signed-off-by: Javier González > --- > drivers/lightnvm/pblk-core.c | 56 ++++++++++++++++++++++++++++++---------- > drivers/lightnvm/pblk-init.c | 14 ++++++++++ > drivers/lightnvm/pblk-map.c | 19 +++++++++----- > drivers/lightnvm/pblk-read.c | 55 +++++++++++++++++++++++++-------------- > drivers/lightnvm/pblk-recovery.c | 34 +++++++++++++++++------- > drivers/lightnvm/pblk.h | 18 ++++++++++--- > 6 files changed, 143 insertions(+), 53 deletions(-) > > diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c > index a311cc29afd8..d52e0047ae9d 100644 > --- a/drivers/lightnvm/pblk-core.c > +++ b/drivers/lightnvm/pblk-core.c > @@ -250,8 +250,20 @@ int pblk_setup_rqd(struct pblk *pblk, struct nvm_rq *rqd, gfp_t mem_flags, > if (!is_vector) > return 0; > > - rqd->ppa_list = rqd->meta_list + pblk_dma_meta_size; > - rqd->dma_ppa_list = rqd->dma_meta_list + pblk_dma_meta_size; > + if (pblk->dma_shared) { > + rqd->ppa_list = rqd->meta_list + pblk->dma_meta_size; > + rqd->dma_ppa_list = rqd->dma_meta_list + pblk->dma_meta_size; > + > + return 0; > + } > + > + rqd->ppa_list = nvm_dev_dma_alloc(dev->parent, mem_flags, > + &rqd->dma_ppa_list); > + if (!rqd->ppa_list) { > + nvm_dev_dma_free(dev->parent, rqd->meta_list, > + rqd->dma_meta_list); > + return -ENOMEM; > + } > > return 0; > } > @@ -262,7 +274,11 @@ void pblk_clear_rqd(struct pblk *pblk, struct nvm_rq *rqd) > > if (rqd->meta_list) > nvm_dev_dma_free(dev->parent, rqd->meta_list, > - rqd->dma_meta_list); > + rqd->dma_meta_list); > + > + if (!pblk->dma_shared && rqd->ppa_list) > + nvm_dev_dma_free(dev->parent, rqd->ppa_list, > + rqd->dma_ppa_list); > } > > /* Caller must guarantee that the request is a valid type */ > @@ -796,10 +812,12 @@ static int pblk_line_smeta_write(struct pblk *pblk, struct pblk_line *line, > rqd.is_seq = 1; > > for (i = 0; i < lm->smeta_sec; i++, paddr++) { > - struct pblk_sec_meta *meta_list = rqd.meta_list; > + struct pblk_sec_meta *meta; > > rqd.ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line->id); > - meta_list[i].lba = lba_list[paddr] = addr_empty; > + > + meta = sec_meta_index(pblk, rqd.meta_list, i); > + meta->lba = lba_list[paddr] = addr_empty; > } > > ret = pblk_submit_io_sync_sem(pblk, &rqd); > @@ -845,8 +863,17 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line, > if (!meta_list) > return -ENOMEM; > > - ppa_list = meta_list + pblk_dma_meta_size; > - dma_ppa_list = dma_meta_list + pblk_dma_meta_size; > + if (pblk->dma_shared) { > + ppa_list = meta_list + pblk->dma_meta_size; > + dma_ppa_list = dma_meta_list + pblk->dma_meta_size; > + } else { > + ppa_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, > + &dma_ppa_list); > + if (!ppa_list) { > + ret = -ENOMEM; > + goto free_meta_list; > + } > + } > > next_rq: > memset(&rqd, 0, sizeof(struct nvm_rq)); > @@ -858,7 +885,7 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line, > l_mg->emeta_alloc_type, GFP_KERNEL); > if (IS_ERR(bio)) { > ret = PTR_ERR(bio); > - goto free_rqd_dma; > + goto free_ppa_list; > } > > bio->bi_iter.bi_sector = 0; /* internal bio */ > @@ -884,7 +911,7 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line, > if (pblk_boundary_paddr_checks(pblk, paddr)) { > bio_put(bio); > ret = -EINTR; > - goto free_rqd_dma; > + goto free_ppa_list; > } > > ppa = addr_to_gen_ppa(pblk, paddr, line_id); > @@ -894,7 +921,7 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line, > if (pblk_boundary_paddr_checks(pblk, paddr + min)) { > bio_put(bio); > ret = -EINTR; > - goto free_rqd_dma; > + goto free_ppa_list; > } > > for (j = 0; j < min; j++, i++, paddr++) > @@ -905,7 +932,7 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line, > if (ret) { > pblk_err(pblk, "emeta I/O submission failed: %d\n", ret); > bio_put(bio); > - goto free_rqd_dma; > + goto free_ppa_list; > } > > atomic_dec(&pblk->inflight_io); > @@ -918,8 +945,11 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line, > if (left_ppas) > goto next_rq; > > -free_rqd_dma: > - nvm_dev_dma_free(dev->parent, rqd.meta_list, rqd.dma_meta_list); > +free_ppa_list: > + if (!pblk->dma_shared) > + nvm_dev_dma_free(dev->parent, ppa_list, dma_ppa_list); > +free_meta_list: > + nvm_dev_dma_free(dev->parent, meta_list, dma_meta_list); > return ret; > } > > diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c > index a99854439224..57972156c318 100644 > --- a/drivers/lightnvm/pblk-init.c > +++ b/drivers/lightnvm/pblk-init.c > @@ -354,6 +354,20 @@ static int pblk_core_init(struct pblk *pblk) > struct nvm_geo *geo = &dev->geo; > int ret, max_write_ppas; > > + if (sizeof(struct pblk_sec_meta) > geo->sos) { > + pblk_err(pblk, "OOB area too small. Min %lu bytes (%d)\n", > + (unsigned long)sizeof(struct pblk_sec_meta), geo->sos); > + return -EINTR; > + } > + > + pblk->dma_ppa_size = (sizeof(u64) * NVM_MAX_VLBA); > + pblk->dma_meta_size = geo->sos * NVM_MAX_VLBA; > + > + if (pblk->dma_ppa_size + pblk->dma_meta_size > PAGE_SIZE) > + pblk->dma_shared = false; > + else > + pblk->dma_shared = true; > + > atomic64_set(&pblk->user_wa, 0); > atomic64_set(&pblk->pad_wa, 0); > atomic64_set(&pblk->gc_wa, 0); > diff --git a/drivers/lightnvm/pblk-map.c b/drivers/lightnvm/pblk-map.c > index dc0efb852475..55fca16d18e4 100644 > --- a/drivers/lightnvm/pblk-map.c > +++ b/drivers/lightnvm/pblk-map.c > @@ -25,6 +25,7 @@ static int pblk_map_page_data(struct pblk *pblk, unsigned int sentry, > unsigned int valid_secs) > { > struct pblk_line *line = pblk_line_get_data(pblk); > + struct pblk_sec_meta *meta; > struct pblk_emeta *emeta; > struct pblk_w_ctx *w_ctx; > __le64 *lba_list; > @@ -56,6 +57,8 @@ static int pblk_map_page_data(struct pblk *pblk, unsigned int sentry, > /* ppa to be sent to the device */ > ppa_list[i] = addr_to_gen_ppa(pblk, paddr, line->id); > > + meta = sec_meta_index(pblk, meta_list, i); > + > /* Write context for target bio completion on write buffer. Note > * that the write buffer is protected by the sync backpointer, > * and a single writer thread have access to each specific entry > @@ -67,14 +70,14 @@ static int pblk_map_page_data(struct pblk *pblk, unsigned int sentry, > kref_get(&line->ref); > w_ctx = pblk_rb_w_ctx(&pblk->rwb, sentry + i); > w_ctx->ppa = ppa_list[i]; > - meta_list[i].lba = cpu_to_le64(w_ctx->lba); > + meta->lba = cpu_to_le64(w_ctx->lba); > lba_list[paddr] = cpu_to_le64(w_ctx->lba); > if (lba_list[paddr] != addr_empty) > line->nr_valid_lbas++; > else > atomic64_inc(&pblk->pad_wa); > } else { > - lba_list[paddr] = meta_list[i].lba = addr_empty; > + lba_list[paddr] = meta->lba = addr_empty; > __pblk_map_invalidate(pblk, line, paddr); > } > } > @@ -87,7 +90,7 @@ void pblk_map_rq(struct pblk *pblk, struct nvm_rq *rqd, unsigned int sentry, > unsigned long *lun_bitmap, unsigned int valid_secs, > unsigned int off) > { > - struct pblk_sec_meta *meta_list = rqd->meta_list; > + struct pblk_sec_meta *meta_list; > struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd); > unsigned int map_secs; > int min = pblk->min_write_pgs; > @@ -95,8 +98,10 @@ void pblk_map_rq(struct pblk *pblk, struct nvm_rq *rqd, unsigned int sentry, > > for (i = off; i < rqd->nr_ppas; i += min) { > map_secs = (i + min > valid_secs) ? (valid_secs % min) : min; > + meta_list = sec_meta_index(pblk, rqd->meta_list, i); > + > if (pblk_map_page_data(pblk, sentry + i, &ppa_list[i], > - lun_bitmap, &meta_list[i], map_secs)) { > + lun_bitmap, meta_list, map_secs)) { > bio_put(rqd->bio); > pblk_free_rqd(pblk, rqd, PBLK_WRITE); > pblk_pipeline_stop(pblk); > @@ -112,8 +117,8 @@ void pblk_map_erase_rq(struct pblk *pblk, struct nvm_rq *rqd, > struct nvm_tgt_dev *dev = pblk->dev; > struct nvm_geo *geo = &dev->geo; > struct pblk_line_meta *lm = &pblk->lm; > - struct pblk_sec_meta *meta_list = rqd->meta_list; > struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd); > + struct pblk_sec_meta *meta_list; > struct pblk_line *e_line, *d_line; > unsigned int map_secs; > int min = pblk->min_write_pgs; > @@ -121,8 +126,10 @@ void pblk_map_erase_rq(struct pblk *pblk, struct nvm_rq *rqd, > > for (i = 0; i < rqd->nr_ppas; i += min) { > map_secs = (i + min > valid_secs) ? (valid_secs % min) : min; > + meta_list = sec_meta_index(pblk, rqd->meta_list, i); > + > if (pblk_map_page_data(pblk, sentry + i, &ppa_list[i], > - lun_bitmap, &meta_list[i], map_secs)) { > + lun_bitmap, meta_list, map_secs)) { > bio_put(rqd->bio); > pblk_free_rqd(pblk, rqd, PBLK_WRITE); > pblk_pipeline_stop(pblk); > diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c > index 57d3155ef9a5..12b690e2abd9 100644 > --- a/drivers/lightnvm/pblk-read.c > +++ b/drivers/lightnvm/pblk-read.c > @@ -42,7 +42,6 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd, > struct bio *bio, sector_t blba, > unsigned long *read_bitmap) > { > - struct pblk_sec_meta *meta_list = rqd->meta_list; > struct ppa_addr ppas[NVM_MAX_VLBA]; > int nr_secs = rqd->nr_ppas; > bool advanced_bio = false; > @@ -51,13 +50,16 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd, > pblk_lookup_l2p_seq(pblk, ppas, blba, nr_secs); > > for (i = 0; i < nr_secs; i++) { > + struct pblk_sec_meta *meta; > struct ppa_addr p = ppas[i]; > sector_t lba = blba + i; > > + meta = sec_meta_index(pblk, rqd->meta_list, i); > retry: > if (pblk_ppa_empty(p)) { > WARN_ON(test_and_set_bit(i, read_bitmap)); > - meta_list[i].lba = cpu_to_le64(ADDR_EMPTY); > + > + meta->lba = cpu_to_le64(ADDR_EMPTY); > > if (unlikely(!advanced_bio)) { > bio_advance(bio, (i) * PBLK_EXPOSED_PAGE_SIZE); > @@ -77,7 +79,7 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd, > goto retry; > } > WARN_ON(test_and_set_bit(i, read_bitmap)); > - meta_list[i].lba = cpu_to_le64(lba); > + meta->lba = cpu_to_le64(lba); > advanced_bio = true; > #ifdef CONFIG_NVM_PBLK_DEBUG > atomic_long_inc(&pblk->cache_reads); > @@ -104,12 +106,15 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd, > static void pblk_read_check_seq(struct pblk *pblk, struct nvm_rq *rqd, > sector_t blba) > { > - struct pblk_sec_meta *meta_lba_list = rqd->meta_list; > int nr_lbas = rqd->nr_ppas; > int i; > > for (i = 0; i < nr_lbas; i++) { > - u64 lba = le64_to_cpu(meta_lba_list[i].lba); > + struct pblk_sec_meta *meta; > + u64 lba; > + > + meta = sec_meta_index(pblk, rqd->meta_list, i); > + lba = le64_to_cpu(meta->lba); > > if (lba == ADDR_EMPTY) > continue; > @@ -133,17 +138,18 @@ static void pblk_read_check_seq(struct pblk *pblk, struct nvm_rq *rqd, > static void pblk_read_check_rand(struct pblk *pblk, struct nvm_rq *rqd, > u64 *lba_list, int nr_lbas) > { > - struct pblk_sec_meta *meta_lba_list = rqd->meta_list; > int i, j; > > for (i = 0, j = 0; i < nr_lbas; i++) { > + struct pblk_sec_meta *meta; > u64 lba = lba_list[i]; > u64 meta_lba; > > if (lba == ADDR_EMPTY) > continue; > > - meta_lba = le64_to_cpu(meta_lba_list[j].lba); > + meta = sec_meta_index(pblk, rqd->meta_list, j); > + meta_lba = le64_to_cpu(meta->lba); > > if (lba != meta_lba) { > #ifdef CONFIG_NVM_PBLK_DEBUG > @@ -218,7 +224,7 @@ static void pblk_end_partial_read(struct nvm_rq *rqd) > struct bio *new_bio = rqd->bio; > struct bio *bio = pr_ctx->orig_bio; > struct bio_vec src_bv, dst_bv; > - struct pblk_sec_meta *meta_list = rqd->meta_list; > + struct pblk_sec_meta *meta; > int bio_init_idx = pr_ctx->bio_init_idx; > unsigned long *read_bitmap = pr_ctx->bitmap; > int nr_secs = pr_ctx->orig_nr_secs; > @@ -237,12 +243,13 @@ static void pblk_end_partial_read(struct nvm_rq *rqd) > } > > /* Re-use allocated memory for intermediate lbas */ > - lba_list_mem = (((void *)rqd->ppa_list) + pblk_dma_ppa_size); > - lba_list_media = (((void *)rqd->ppa_list) + 2 * pblk_dma_ppa_size); > + lba_list_mem = (((void *)rqd->ppa_list) + pblk->dma_ppa_size); > + lba_list_media = (((void *)rqd->ppa_list) + 2 * pblk->dma_ppa_size); > > for (i = 0; i < nr_secs; i++) { > - lba_list_media[i] = meta_list[i].lba; > - meta_list[i].lba = lba_list_mem[i]; > + meta = sec_meta_index(pblk, rqd->meta_list, i); > + lba_list_media[i] = meta->lba; > + meta->lba = lba_list_mem[i]; > } > > /* Fill the holes in the original bio */ > @@ -254,7 +261,8 @@ static void pblk_end_partial_read(struct nvm_rq *rqd) > line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]); > kref_put(&line->ref, pblk_line_put); > > - meta_list[hole].lba = lba_list_media[i]; > + meta = sec_meta_index(pblk, rqd->meta_list, hole); > + meta->lba = lba_list_media[i]; > > src_bv = new_bio->bi_io_vec[i++]; > dst_bv = bio->bi_io_vec[bio_init_idx + hole]; > @@ -290,8 +298,8 @@ static int pblk_setup_partial_read(struct pblk *pblk, struct nvm_rq *rqd, > unsigned long *read_bitmap, > int nr_holes) > { > - struct pblk_sec_meta *meta_list = rqd->meta_list; > struct pblk_g_ctx *r_ctx = nvm_rq_to_pdu(rqd); > + struct pblk_sec_meta *meta; > struct pblk_pr_ctx *pr_ctx; > struct bio *new_bio, *bio = r_ctx->private; > __le64 *lba_list_mem; > @@ -299,7 +307,7 @@ static int pblk_setup_partial_read(struct pblk *pblk, struct nvm_rq *rqd, > int i; > > /* Re-use allocated memory for intermediate lbas */ > - lba_list_mem = (((void *)rqd->ppa_list) + pblk_dma_ppa_size); > + lba_list_mem = (((void *)rqd->ppa_list) + pblk->dma_ppa_size); > > new_bio = bio_alloc(GFP_KERNEL, nr_holes); > > @@ -315,8 +323,10 @@ static int pblk_setup_partial_read(struct pblk *pblk, struct nvm_rq *rqd, > if (!pr_ctx) > goto fail_free_pages; > > - for (i = 0; i < nr_secs; i++) > - lba_list_mem[i] = meta_list[i].lba; > + for (i = 0; i < nr_secs; i++) { > + meta = sec_meta_index(pblk, rqd->meta_list, i); > + lba_list_mem[i] = meta->lba; > + } > > new_bio->bi_iter.bi_sector = 0; /* internal bio */ > bio_set_op_attrs(new_bio, REQ_OP_READ, 0); > @@ -382,7 +392,7 @@ static int pblk_partial_read_bio(struct pblk *pblk, struct nvm_rq *rqd, > static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd, struct bio *bio, > sector_t lba, unsigned long *read_bitmap) > { > - struct pblk_sec_meta *meta_list = rqd->meta_list; > + struct pblk_sec_meta *meta; > struct ppa_addr ppa; > > pblk_lookup_l2p_seq(pblk, &ppa, lba, 1); > @@ -394,7 +404,10 @@ static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd, struct bio *bio, > retry: > if (pblk_ppa_empty(ppa)) { > WARN_ON(test_and_set_bit(0, read_bitmap)); > - meta_list[0].lba = cpu_to_le64(ADDR_EMPTY); > + > + meta = sec_meta_index(pblk, rqd->meta_list, 0); > + meta->lba = cpu_to_le64(ADDR_EMPTY); > + > return; > } > > @@ -408,7 +421,9 @@ static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd, struct bio *bio, > } > > WARN_ON(test_and_set_bit(0, read_bitmap)); > - meta_list[0].lba = cpu_to_le64(lba); > + > + meta = sec_meta_index(pblk, rqd->meta_list, 0); > + meta->lba = cpu_to_le64(lba); > > #ifdef CONFIG_NVM_PBLK_DEBUG > atomic_long_inc(&pblk->cache_reads); > diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c > index 8114013c37b8..1ce92562603d 100644 > --- a/drivers/lightnvm/pblk-recovery.c > +++ b/drivers/lightnvm/pblk-recovery.c > @@ -157,7 +157,7 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line, > { > struct nvm_tgt_dev *dev = pblk->dev; > struct nvm_geo *geo = &dev->geo; > - struct pblk_sec_meta *meta_list; > + struct pblk_sec_meta *meta; > struct pblk_pad_rq *pad_rq; > struct nvm_rq *rqd; > struct bio *bio; > @@ -218,8 +218,6 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line, > rqd->end_io = pblk_end_io_recov; > rqd->private = pad_rq; > > - meta_list = rqd->meta_list; > - > for (i = 0; i < rqd->nr_ppas; ) { > struct ppa_addr ppa; > int pos; > @@ -241,8 +239,10 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line, > dev_ppa = addr_to_gen_ppa(pblk, w_ptr, line->id); > > pblk_map_invalidate(pblk, dev_ppa); > - lba_list[w_ptr] = meta_list[i].lba = addr_empty; > rqd->ppa_list[i] = dev_ppa; > + > + meta = sec_meta_index(pblk, rqd->meta_list, i); > + lba_list[w_ptr] = meta->lba = addr_empty; > } > } > > @@ -327,7 +327,7 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line, > struct nvm_tgt_dev *dev = pblk->dev; > struct nvm_geo *geo = &dev->geo; > struct ppa_addr *ppa_list; > - struct pblk_sec_meta *meta_list; > + struct pblk_sec_meta *meta_list, *meta; > struct nvm_rq *rqd; > struct bio *bio; > void *data; > @@ -425,7 +425,10 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line, > } > > for (i = 0; i < rqd->nr_ppas; i++) { > - u64 lba = le64_to_cpu(meta_list[i].lba); > + u64 lba; > + > + meta = sec_meta_index(pblk, meta_list, i); > + lba = le64_to_cpu(meta->lba); > > lba_list[paddr++] = cpu_to_le64(lba); > > @@ -464,13 +467,22 @@ static int pblk_recov_l2p_from_oob(struct pblk *pblk, struct pblk_line *line) > if (!meta_list) > return -ENOMEM; > > - ppa_list = (void *)(meta_list) + pblk_dma_meta_size; > - dma_ppa_list = dma_meta_list + pblk_dma_meta_size; > + if (pblk->dma_shared) { > + ppa_list = (void *)(meta_list) + pblk->dma_meta_size; > + dma_ppa_list = dma_meta_list + pblk->dma_meta_size; > + } else { > + ppa_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, > + &dma_ppa_list); > + if (!ppa_list) { > + ret = -ENOMEM; > + goto free_meta_list; > + } > + } > > data = kcalloc(pblk->max_write_pgs, geo->csecs, GFP_KERNEL); > if (!data) { > ret = -ENOMEM; > - goto free_meta_list; > + goto free_ppa_list; > } > > rqd = mempool_alloc(&pblk->r_rq_pool, GFP_KERNEL); > @@ -495,9 +507,11 @@ static int pblk_recov_l2p_from_oob(struct pblk *pblk, struct pblk_line *line) > out: > mempool_free(rqd, &pblk->r_rq_pool); > kfree(data); > +free_ppa_list: > + if (!pblk->dma_shared) > + nvm_dev_dma_free(dev->parent, ppa_list, dma_ppa_list); > free_meta_list: > nvm_dev_dma_free(dev->parent, meta_list, dma_meta_list); > - > return ret; > } > > diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h > index 22cc9bfbbb10..4526fee206d9 100644 > --- a/drivers/lightnvm/pblk.h > +++ b/drivers/lightnvm/pblk.h > @@ -86,7 +86,6 @@ enum { > }; > > struct pblk_sec_meta { > - u64 reserved; > __le64 lba; > }; > > @@ -103,9 +102,6 @@ enum { > PBLK_RL_LOW = 4 > }; > > -#define pblk_dma_meta_size (sizeof(struct pblk_sec_meta) * NVM_MAX_VLBA) > -#define pblk_dma_ppa_size (sizeof(u64) * NVM_MAX_VLBA) > - > /* write buffer completion context */ > struct pblk_c_ctx { > struct list_head list; /* Head for out-of-order completion */ > @@ -637,6 +633,10 @@ struct pblk { > > int sec_per_write; > > + int dma_meta_size; > + int dma_ppa_size; > + bool dma_shared; > + > unsigned char instance_uuid[16]; > > /* Persistent write amplification counters, 4kb sector I/Os */ > @@ -985,6 +985,16 @@ static inline void *emeta_to_vsc(struct pblk *pblk, struct line_emeta *emeta) > return (emeta_to_lbas(pblk, emeta) + pblk->lm.emeta_len[2]); > } > > +static inline struct pblk_sec_meta *sec_meta_index(struct pblk *pblk, > + struct pblk_sec_meta *meta, > + int index) > +{ > + struct nvm_tgt_dev *dev = pblk->dev; > + struct nvm_geo *geo = &dev->geo; > + > + return ((void *)meta + index * geo->sos); > +} > + > static inline int pblk_line_vsc(struct pblk_line *line) > { > return le32_to_cpu(*line->vsc); > It will be helpful to split this patch into two: - One that does the 8b conversion - One that makes the change to merge metadata and ppa list data buffers - How about making it a simplification to only allow up to 32b metadata buffers, then one doesn't have to think about it crossing multiple pages. - You can also make a structure for it, use the first 3.5KB for meta, and the next 512B for PPAs.