Re: [PATCH v3 5/5] lightnvm: pblk: Support for packed metadata

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> On 23 Nov 2018, at 16.45, Igor Konopko <igor.j.konopko@xxxxxxxxx> wrote:
> 
> In current pblk implementation, l2p mapping for not closed lines
> is always stored only in OOB metadata and recovered from it.
> 
> Such a solution does not provide data integrity when drives does
> not have such a OOB metadata space.
> 
> The goal of this patch is to add support for so called packed
> metadata, which store l2p mapping for open lines in last sector
> of every write unit.
> 
> After this set of changes, drives with OOB >0 and <16b are still
> not supported.
> 
> Signed-off-by: Igor Konopko <igor.j.konopko@xxxxxxxxx>
> ---
> drivers/lightnvm/pblk-core.c     | 53 +++++++++++++++++++++++++++++++++++++---
> drivers/lightnvm/pblk-init.c     | 37 +++++++++++++++++++++++++---
> drivers/lightnvm/pblk-rb.c       |  3 +++
> drivers/lightnvm/pblk-read.c     |  6 +++++
> drivers/lightnvm/pblk-recovery.c |  5 ++--
> drivers/lightnvm/pblk-sysfs.c    |  7 ++++++
> drivers/lightnvm/pblk-write.c    | 14 ++++++++---
> drivers/lightnvm/pblk.h          | 10 +++++++-
> 8 files changed, 121 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
> index 2ebd3b079a96..615817bf97e3 100644
> --- a/drivers/lightnvm/pblk-core.c
> +++ b/drivers/lightnvm/pblk-core.c
> @@ -376,7 +376,7 @@ void pblk_write_should_kick(struct pblk *pblk)
> {
> 	unsigned int secs_avail = pblk_rb_read_count(&pblk->rwb);
> 
> -	if (secs_avail >= pblk->min_write_pgs)
> +	if (secs_avail >= pblk->min_write_pgs_data)
> 		pblk_write_kick(pblk);
> }
> 
> @@ -407,7 +407,9 @@ struct list_head *pblk_line_gc_list(struct pblk *pblk, struct pblk_line *line)
> 	struct pblk_line_meta *lm = &pblk->lm;
> 	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> 	struct list_head *move_list = NULL;
> -	int vsc = le32_to_cpu(*line->vsc);
> +	int packed_meta = (le32_to_cpu(*line->vsc) / pblk->min_write_pgs_data)
> +			* (pblk->min_write_pgs - pblk->min_write_pgs_data);
> +	int vsc = le32_to_cpu(*line->vsc) + packed_meta;
> 
> 	lockdep_assert_held(&line->lock);
> 
> @@ -620,12 +622,15 @@ struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
> }
> 
> int pblk_calc_secs(struct pblk *pblk, unsigned long secs_avail,
> -		   unsigned long secs_to_flush)
> +		   unsigned long secs_to_flush, bool skip_meta)
> {
> 	int max = pblk->sec_per_write;
> 	int min = pblk->min_write_pgs;
> 	int secs_to_sync = 0;
> 
> +	if (skip_meta && pblk->min_write_pgs_data != pblk->min_write_pgs)
> +		min = max = pblk->min_write_pgs_data;
> +
> 	if (secs_avail >= max)
> 		secs_to_sync = max;
> 	else if (secs_avail >= min)
> @@ -852,7 +857,7 @@ int pblk_line_emeta_read(struct pblk *pblk, struct pblk_line *line,
> next_rq:
> 	memset(&rqd, 0, sizeof(struct nvm_rq));
> 
> -	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0);
> +	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
> 	rq_len = rq_ppas * geo->csecs;
> 
> 	bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len,
> @@ -2161,3 +2166,43 @@ void pblk_lookup_l2p_rand(struct pblk *pblk, struct ppa_addr *ppas,
> 	}
> 	spin_unlock(&pblk->trans_lock);
> }
> +
> +void pblk_set_packed_meta(struct pblk *pblk, struct nvm_rq *rqd)
> +{
> +	void *meta_list = rqd->meta_list;
> +	void *page;
> +	int i = 0;
> +
> +	if (pblk_is_oob_meta_supported(pblk))
> +		return;
> +
> +	/* We need to zero out metadata corresponding to packed meta page */
> +	pblk_get_meta(pblk, meta_list, rqd->nr_ppas - 1)->lba =
> +						cpu_to_le64(ADDR_EMPTY);
> +
> +	page = page_to_virt(rqd->bio->bi_io_vec[rqd->bio->bi_vcnt - 1].bv_page);
> +	/* We need to fill last page of request (packed metadata)
> +	 * with data from oob meta buffer.
> +	 */
> +	for (; i < rqd->nr_ppas; i++)
> +		memcpy(page + (i * sizeof(struct pblk_sec_meta)),
> +			pblk_get_meta(pblk, meta_list, i),
> +			sizeof(struct pblk_sec_meta));

You are doing an unnecessary memory copy here, using the metadata buffer
as a bouncing buffer on the packed metadata path. Why not do this
directly on pblk_map_page_data()? At this point you have already created
the bio and have all the necessary structures in place and can simply
write to the last page instead of writing to the metadata buffer.


Attachment: signature.asc
Description: Message signed with OpenPGP


[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux