lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Thu, 18 Feb 2016 08:57:46 +0100
From:	Matias Bjørling <mb@...htnvm.io>
To:	Javier González <jg@...htnvm.io>
Cc:	linux-kernel@...r.kernel.org, linux-block@...r.kernel.org,
	Javier González <javier@...xlabs.com>
Subject: Re: [PATCH] lightnvm: generalize rrpc ppa calculations

On 02/17/2016 12:00 PM, Javier González wrote:
> 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 <javier@...xlabs.com>
> ---
>  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;
> 

Thanks Javier, applied.

-Matias

Powered by blists - more mailing lists