All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wenwei Tao <ww.tao0320@gmail.com>
To: "Matias Bjørling" <mb@lightnvm.io>
Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
Subject: Re: [PATCH v2 2/2] lightnvm: add non-continuous lun target creation support
Date: Thu, 28 Jan 2016 16:50:06 +0800	[thread overview]
Message-ID: <CACygaLC80YQir5w+XbZi=yvCL_+BozCok1wp1j6rJ2MTZqRF9Q@mail.gmail.com> (raw)
In-Reply-To: <56A89169.6030704@lightnvm.io>

2016-01-27 17:44 GMT+08:00 Matias Bjørling <mb@lightnvm.io>:
> On 01/26/2016 01:33 PM, Wenwei Tao wrote:
>> When create a target, we specify the begin lunid and
>> the end lunid, and get the corresponding continuous
>> luns from media manager, if one of the luns is not free,
>> we failed to create the target, even if the device's
>> total free luns are enough.
>>
>> So add non-continuous lun target creation support,
>> thus we can improve the backend device's space utilization.
>> Signed-off-by: Wenwei Tao <ww.tao0320@gmail.com>
>> ---
>> Changes since v1:
>> -use NVM_FIXED instead NVM_C_FIXED in gennvm_get_lun
>> -add target creation flags check
>> -rebase to v4.5-rc1
>>
>>  drivers/lightnvm/core.c       |  36 ++++---
>>  drivers/lightnvm/gennvm.c     |  42 ++++++++-
>>  drivers/lightnvm/rrpc.c       | 215 +++++++++++++++++++++++++++---------------
>>  drivers/lightnvm/rrpc.h       |   6 +-
>>  include/linux/lightnvm.h      |  24 ++++-
>>  include/uapi/linux/lightnvm.h |   3 +
>>  6 files changed, 229 insertions(+), 97 deletions(-)
>>
>
> Hi Wenwei,
>
> I did some digging on the patch and changed the interface to a
> reserve/release interface. I also removed the logic to dynamically
> select another lun than the one requested.
>
> A couple of questions:
>
>  1. The rrpc_lun->rev_lock and rev_trans_map change; this might be for
> another patch, and it isn't directly related to continuous mapping?

rrpc_lun->rev_lock and rev_trans_map change is related to
non-continuous mapping, it's not directly related to continuous
mapping.
Put this change in  another patch along with non-continuous mapping
support and this patch would be only add reserve/release thing, is
that your suggestion?


>  2. Instead of dynamically assigning new luns when not available, what
> about taking a list of lun ids instead?
>

Seems you prefer user make the choice ?
But the target creation can still fail if one of the list lun ids is
not available although there may be enough free luns.

> I would only implement this in the lnvm ioctl interface. It would allow
> a list of lun ids to be passed through the lnvm ioctl interface. This
> way, the NVM_CONFIG_TYPE_SIMPLE can be extended with another
> NVM_CONFIG_TYPE_LIST, or similar, which then parses the ioctl
> appropriately. Would that be a better way to do it?
>
> Here is the diff. It is also rebased on top of the two latest patches
> that which are sent up for the next -rc.
>
> Thanks
>
> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
> index 27a59e8..59a4bf9 100644
> --- a/drivers/lightnvm/core.c
> +++ b/drivers/lightnvm/core.c
> @@ -468,6 +468,11 @@ static int nvm_core_init(struct nvm_dev *dev)
>                                 dev->luns_per_chnl *
>                                 dev->nr_chnls;
>         dev->total_pages = dev->total_blocks * dev->pgs_per_blk;
> +       dev->lun_map = kcalloc(BITS_TO_LONGS(dev->nr_luns),
> +                       sizeof(unsigned long), GFP_KERNEL);
> +       if (!dev->lun_map)
> +               return -ENOMEM;
> +
>         INIT_LIST_HEAD(&dev->online_targets);
>         mutex_init(&dev->mlock);
>         spin_lock_init(&dev->lock);
> @@ -610,6 +615,7 @@ void nvm_unregister(char *disk_name)
>         up_write(&nvm_lock);
>
>         nvm_exit(dev);
> +       kfree(dev->lun_map);
>         kfree(dev);
>  }
>  EXPORT_SYMBOL(nvm_unregister);
> diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c
> index 6e2685d..6419898 100644
> --- a/drivers/lightnvm/gennvm.c
> +++ b/drivers/lightnvm/gennvm.c
> @@ -188,6 +188,9 @@ static int gennvm_block_map(u64 slba, u32 nlb,
> __le64 *entries, void *private)
>                 lun_id = div_u64(pba, dev->sec_per_lun);
>                 lun = &gn->luns[lun_id];
>
> +               if (!test_bit(lun_id, dev->lun_map))
> +                       __set_bit(lun_id, dev->lun_map);
> +
>                 /* Calculate block offset into lun */
>                 pba = pba - (dev->sec_per_lun * lun_id);
>                 blk = &lun->vlun.blocks[div_u64(pba, dev->sec_per_blk)];
> @@ -478,10 +481,23 @@ static int gennvm_erase_blk(struct nvm_dev *dev,
> struct nvm_block *blk,
>         return nvm_erase_ppa(dev, &addr, 1);
>  }
>
> +static int gennvm_reserve_lun(struct nvm_dev *dev, int lunid)
> +{
> +       return test_and_set_bit(lunid, dev->lun_map);
> +}
> +
> +static void gennvm_release_lun(struct nvm_dev *dev, int lunid)
> +{
> +       WARN_ON(!test_and_clear_bit(lunid, dev->lun_map));
> +}
> +
>  static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid)
>  {
>         struct gen_nvm *gn = dev->mp;
>
> +       if (unlikely(lunid >= dev->nr_luns))
> +               return NULL;
> +
>         return &gn->luns[lunid].vlun;
>  }
>
> @@ -523,6 +539,8 @@ static struct nvmm_type gennvm = {
>         .erase_blk              = gennvm_erase_blk,
>
>         .get_lun                = gennvm_get_lun,
> +       .reserve_lun            = gennvm_reserve_lun,
> +       .release_lun            = gennvm_release_lun,
>         .lun_info_print         = gennvm_lun_info_print,
>
>         .get_area               = gennvm_get_area,
> diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c
> index 20afe1c..0a99ebc 100644
> --- a/drivers/lightnvm/rrpc.c
> +++ b/drivers/lightnvm/rrpc.c
> @@ -26,25 +26,32 @@ static int rrpc_submit_io(struct rrpc *rrpc, struct
> bio *bio,
>                 for ((i) = 0, rlun = &(rrpc)->luns[0]; \
>                         (i) < (rrpc)->nr_luns; (i)++, rlun = &(rrpc)->luns[(i)])
>
> +static inline u64 lun_poffset(struct nvm_dev *dev, struct nvm_lun *lun)
> +{
> +       return lun->id * dev->sec_per_lun;
> +}
> +
>  static void rrpc_page_invalidate(struct rrpc *rrpc, struct rrpc_addr *a)
>  {
>         struct rrpc_block *rblk = a->rblk;
> -       unsigned int pg_offset;
> +       struct rrpc_lun *rlun = rblk->rlun;
> +       u64 pg_offset;
>
> -       lockdep_assert_held(&rrpc->rev_lock);
> +       lockdep_assert_held(&rlun->rev_lock);
>
>         if (a->addr == ADDR_EMPTY || !rblk)
>                 return;
>
>         spin_lock(&rblk->lock);
>
> -       div_u64_rem(a->addr, rrpc->dev->pgs_per_blk, &pg_offset);
> +       div_u64_rem(a->addr, rrpc->dev->pgs_per_blk, (u32 *)&pg_offset);
>         WARN_ON(test_and_set_bit(pg_offset, rblk->invalid_pages));
>         rblk->nr_invalid_pages++;
>
>         spin_unlock(&rblk->lock);
>
> -       rrpc->rev_trans_map[a->addr - rrpc->poffset].addr = ADDR_EMPTY;
> +       pg_offset = lun_poffset(rrpc->dev, rlun->parent);
> +       rlun->rev_trans_map[a->addr - pg_offset].addr = ADDR_EMPTY;
>  }
>
>  static void rrpc_invalidate_range(struct rrpc *rrpc, sector_t slba,
> @@ -52,14 +59,15 @@ static void rrpc_invalidate_range(struct rrpc *rrpc,
> sector_t slba,
>  {
>         sector_t i;
>
> -       spin_lock(&rrpc->rev_lock);
>         for (i = slba; i < slba + len; i++) {
>                 struct rrpc_addr *gp = &rrpc->trans_map[i];
> +               struct rrpc_lun *rlun = gp->rblk->rlun;
>
> +               spin_lock(&rlun->rev_lock);
>                 rrpc_page_invalidate(rrpc, gp);
> +               spin_unlock(&rlun->rev_lock);
>                 gp->rblk = NULL;
>         }
> -       spin_unlock(&rrpc->rev_lock);
>  }
>
>  static struct nvm_rq *rrpc_inflight_laddr_acquire(struct rrpc *rrpc,
> @@ -281,13 +289,14 @@ static void rrpc_end_sync_bio(struct bio *bio)
>  static int rrpc_move_valid_pages(struct rrpc *rrpc, struct rrpc_block
> *rblk)
>  {
>         struct request_queue *q = rrpc->dev->q;
> +       struct rrpc_lun *rlun = rblk->rlun;
>         struct rrpc_rev_addr *rev;
>         struct nvm_rq *rqd;
>         struct bio *bio;
>         struct page *page;
>         int slot;
>         int nr_pgs_per_blk = rrpc->dev->pgs_per_blk;
> -       u64 phys_addr;
> +       u64 phys_addr, poffset;
>         DECLARE_COMPLETION_ONSTACK(wait);
>
>         if (bitmap_full(rblk->invalid_pages, nr_pgs_per_blk))
> @@ -303,6 +312,7 @@ static int rrpc_move_valid_pages(struct rrpc *rrpc,
> struct rrpc_block *rblk)
>         if (!page)
>                 return -ENOMEM;
>
> +       poffset = lun_poffset(rrpc->dev, rlun->parent);
>         while ((slot = find_first_zero_bit(rblk->invalid_pages,
>                                             nr_pgs_per_blk)) < nr_pgs_per_blk) {
>
> @@ -310,23 +320,23 @@ static int rrpc_move_valid_pages(struct rrpc
> *rrpc, struct rrpc_block *rblk)
>                 phys_addr = (rblk->parent->id * nr_pgs_per_blk) + slot;
>
>  try:
> -               spin_lock(&rrpc->rev_lock);
> +               spin_lock(&rlun->rev_lock);
>                 /* Get logical address from physical to logical table */
> -               rev = &rrpc->rev_trans_map[phys_addr - rrpc->poffset];
> +               rev = &rlun->rev_trans_map[phys_addr - poffset];
>                 /* already updated by previous regular write */
>                 if (rev->addr == ADDR_EMPTY) {
> -                       spin_unlock(&rrpc->rev_lock);
> +                       spin_unlock(&rlun->rev_lock);
>                         continue;
>                 }
>
>                 rqd = rrpc_inflight_laddr_acquire(rrpc, rev->addr, 1);
>                 if (IS_ERR_OR_NULL(rqd)) {
> -                       spin_unlock(&rrpc->rev_lock);
> +                       spin_unlock(&rlun->rev_lock);
>                         schedule();
>                         goto try;
>                 }
>
> -               spin_unlock(&rrpc->rev_lock);
> +               spin_unlock(&rlun->rev_lock);
>
>                 /* Perform read to do GC */
>                 bio->bi_iter.bi_sector = rrpc_get_sector(rev->addr);
> @@ -395,7 +405,7 @@ static void rrpc_block_gc(struct work_struct *work)
>         struct rrpc_block *rblk = gcb->rblk;
>         struct nvm_dev *dev = rrpc->dev;
>         struct nvm_lun *lun = rblk->parent->lun;
> -       struct rrpc_lun *rlun = &rrpc->luns[lun->id - rrpc->lun_offset];
> +       struct rrpc_lun *rlun = lun->private;
>
>         mempool_free(gcb, rrpc->gcb_pool);
>         pr_debug("nvm: block '%lu' being reclaimed\n", rblk->parent->id);
> @@ -496,9 +506,9 @@ static void rrpc_gc_queue(struct work_struct *work)
>                                                                         ws_gc);
>         struct rrpc *rrpc = gcb->rrpc;
>         struct rrpc_block *rblk = gcb->rblk;
> -       struct nvm_lun *lun = rblk->parent->lun;
>         struct nvm_block *blk = rblk->parent;
> -       struct rrpc_lun *rlun = &rrpc->luns[lun->id - rrpc->lun_offset];
> +       struct nvm_lun *lun = blk->lun;
> +       struct rrpc_lun *rlun = lun->private;
>
>         spin_lock(&rlun->lock);
>         list_add_tail(&rblk->prio, &rlun->prio_list);
> @@ -549,22 +559,24 @@ static struct rrpc_lun *rrpc_get_lun_rr(struct
> rrpc *rrpc, int is_gc)
>  static struct rrpc_addr *rrpc_update_map(struct rrpc *rrpc, sector_t laddr,
>                                         struct rrpc_block *rblk, u64 paddr)
>  {
> +       struct rrpc_lun *rlun = rblk->rlun;
>         struct rrpc_addr *gp;
>         struct rrpc_rev_addr *rev;
> +       u64 poffset = lun_poffset(rrpc->dev, rlun->parent);
>
>         BUG_ON(laddr >= rrpc->nr_pages);
>
>         gp = &rrpc->trans_map[laddr];
> -       spin_lock(&rrpc->rev_lock);
> +       spin_lock(&rlun->rev_lock);
>         if (gp->rblk)
>                 rrpc_page_invalidate(rrpc, gp);
>
>         gp->addr = paddr;
>         gp->rblk = rblk;
>
> -       rev = &rrpc->rev_trans_map[gp->addr - rrpc->poffset];
> +       rev = &rlun->rev_trans_map[gp->addr - poffset];
>         rev->addr = laddr;
> -       spin_unlock(&rrpc->rev_lock);
> +       spin_unlock(&rlun->rev_lock);
>
>         return gp;
>  }
> @@ -953,8 +965,6 @@ static void rrpc_requeue(struct work_struct *work)
>
>  static void rrpc_gc_free(struct rrpc *rrpc)
>  {
> -       struct rrpc_lun *rlun;
> -       int i;
>
>         if (rrpc->krqd_wq)
>                 destroy_workqueue(rrpc->krqd_wq);
> @@ -962,16 +972,6 @@ static void rrpc_gc_free(struct rrpc *rrpc)
>         if (rrpc->kgc_wq)
>                 destroy_workqueue(rrpc->kgc_wq);
>
> -       if (!rrpc->luns)
> -               return;
> -
> -       for (i = 0; i < rrpc->nr_luns; i++) {
> -               rlun = &rrpc->luns[i];
> -
> -               if (!rlun->blocks)
> -                       break;
> -               vfree(rlun->blocks);
> -       }
>  }
>
>  static int rrpc_gc_init(struct rrpc *rrpc)
> @@ -992,7 +992,6 @@ static int rrpc_gc_init(struct rrpc *rrpc)
>
>  static void rrpc_map_free(struct rrpc *rrpc)
>  {
> -       vfree(rrpc->rev_trans_map);
>         vfree(rrpc->trans_map);
>  }
>
> @@ -1000,19 +999,28 @@ static int rrpc_l2p_update(u64 slba, u32 nlb,
> __le64 *entries, void *private)
>  {
>         struct rrpc *rrpc = (struct rrpc *)private;
>         struct nvm_dev *dev = rrpc->dev;
> -       struct rrpc_addr *addr = rrpc->trans_map + slba;
> -       struct rrpc_rev_addr *raddr = rrpc->rev_trans_map;
> +       struct rrpc_addr *addr;
> +       struct rrpc_rev_addr *raddr;
>         sector_t max_pages = dev->total_pages * (dev->sec_size >> 9);
> -       u64 elba = slba + nlb;
> -       u64 i;
> +       int page_size = dev->sec_per_pg * dev->sec_size;
> +       u64 elba, i;
> +
> +       elba = slba + nlb;
>
>         if (unlikely(elba > dev->total_pages)) {
>                 pr_err("nvm: L2P data from device is out of bounds!\n");
>                 return -EINVAL;
>         }
>
> +       slba -= rrpc->soffset >> (ilog2(page_size) - 9);
> +       addr = rrpc->trans_map + slba;
>         for (i = 0; i < nlb; i++) {
> +               struct rrpc_lun *rlun;
> +               struct nvm_lun *lun;
>                 u64 pba = le64_to_cpu(entries[i]);
> +               u64 poffset;
> +               int lunid;
> +
>                 /* LNVM treats address-spaces as silos, LBA and PBA are
>                  * equally large and zero-indexed.
>                  */
> @@ -1028,8 +1036,15 @@ static int rrpc_l2p_update(u64 slba, u32 nlb,
> __le64 *entries, void *private)
>                 if (!pba)
>                         continue;
>
> +               lunid = div_u64(pba, dev->sec_per_lun);
> +               lun = dev->mt->get_lun(dev, lunid);
> +               if (unlikely(!lun))
> +                       return -EINVAL;
> +               rlun = lun->private;
> +               raddr = rlun->rev_trans_map;
> +               poffset = lun_poffset(dev, lun);
>                 addr[i].addr = pba;
> -               raddr[pba].addr = slba + i;
> +               raddr[pba - poffset].addr = slba + i;
>         }
>
>         return 0;
> @@ -1049,17 +1064,11 @@ static int rrpc_map_init(struct rrpc *rrpc)
>         if (!rrpc->trans_map)
>                 return -ENOMEM;
>
> -       rrpc->rev_trans_map = vmalloc(sizeof(struct rrpc_rev_addr)
> -                                                       * rrpc->nr_pages);
> -       if (!rrpc->rev_trans_map)
> -               return -ENOMEM;
>
>         for (i = 0; i < rrpc->nr_pages; i++) {
>                 struct rrpc_addr *p = &rrpc->trans_map[i];
> -               struct rrpc_rev_addr *r = &rrpc->rev_trans_map[i];
>
>                 p->addr = ADDR_EMPTY;
> -               r->addr = ADDR_EMPTY;
>         }
>
>         if (!dev->ops->get_l2p_tbl)
> @@ -1130,22 +1139,86 @@ static void rrpc_core_free(struct rrpc *rrpc)
>
>  static void rrpc_luns_free(struct rrpc *rrpc)
>  {
> +       struct nvm_dev *dev = rrpc->dev;
> +       struct rrpc_lun *rlun;
> +       struct nvm_lun *lun;
> +       int i;
> +
> +       if (!rrpc->luns)
> +               return;
> +
> +       for (i = 0; i < rrpc->nr_luns; i++) {
> +               rlun = &rrpc->luns[i];
> +               if (!rlun)
> +                       break;
> +               lun = rlun->parent;
> +               dev->mt->release_lun(dev, lun->id);
> +               vfree(rlun->rev_trans_map);
> +               vfree(rlun->blocks);
> +       }
>         kfree(rrpc->luns);
> +       rrpc->luns = NULL;
> +
> +}
> +
> +static int rrpc_lun_init(struct rrpc *rrpc, struct rrpc_lun *rlun,
> +                                                       struct nvm_lun *lun)
> +{
> +       struct nvm_dev *dev = rrpc->dev;
> +       int i;
> +
> +       rlun->rrpc = rrpc;
> +       rlun->parent = lun;
> +
> +       rlun->rev_trans_map = vmalloc(sizeof(struct rrpc_rev_addr) *
> +                                                       dev->sec_per_lun);
> +       if (!rlun->rev_trans_map)
> +               return -ENOMEM;
> +
> +       for (i = 0; i < dev->sec_per_lun; i++) {
> +               struct rrpc_rev_addr *r = &rlun->rev_trans_map[i];
> +
> +               r->addr = ADDR_EMPTY;
> +       }
> +
> +       rlun->blocks = vzalloc(sizeof(struct rrpc_block) * dev->blks_per_lun);
> +       if (!rlun->blocks) {
> +               vfree(rlun->rev_trans_map);
> +               return -ENOMEM;
> +       }
> +
> +       for (i = 0; i < dev->blks_per_lun; i++) {
> +               struct rrpc_block *rblk = &rlun->blocks[i];
> +               struct nvm_block *blk = &lun->blocks[i];
> +
> +               rblk->parent = blk;
> +               rblk->rlun = rlun;
> +               INIT_LIST_HEAD(&rblk->prio);
> +               spin_lock_init(&rblk->lock);
> +       }
> +
> +       lun->private = rlun;
> +       INIT_LIST_HEAD(&rlun->prio_list);
> +       INIT_LIST_HEAD(&rlun->open_list);
> +       INIT_LIST_HEAD(&rlun->closed_list);
> +       INIT_WORK(&rlun->ws_gc, rrpc_lun_gc);
> +       spin_lock_init(&rlun->lock);
> +       spin_lock_init(&rlun->rev_lock);
> +
> +       return 0;
>  }
>
>  static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end)
>  {
>         struct nvm_dev *dev = rrpc->dev;
>         struct rrpc_lun *rlun;
> -       int i, j;
> +       int i, ret;
>
>         if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) {
>                 pr_err("rrpc: number of pages per block too high.");
>                 return -EINVAL;
>         }
>
> -       spin_lock_init(&rrpc->rev_lock);
> -
>         rrpc->luns = kcalloc(rrpc->nr_luns, sizeof(struct rrpc_lun),
>                                                                 GFP_KERNEL);
>         if (!rrpc->luns)
> @@ -1153,40 +1226,35 @@ static int rrpc_luns_init(struct rrpc *rrpc, int
> lun_begin, int lun_end)
>
>         /* 1:1 mapping */
>         for (i = 0; i < rrpc->nr_luns; i++) {
> -               struct nvm_lun *lun = dev->mt->get_lun(dev, lun_begin + i);
> +               int lunid = lun_begin + i;
> +               struct nvm_lun *lun;
> +
> +               if (dev->mt->reserve_lun(dev, lunid)) {
> +                       pr_err("rrpc: lun %u is already allocated\n", lunid);
> +                       ret = -EINVAL;
> +                       goto err;
> +               }
> +
> +               lun = dev->mt->get_lun(dev, lunid);
> +               if (!lun) {
> +                       ret = -EINVAL;
> +                       goto err;
> +               }
>
>                 rlun = &rrpc->luns[i];
> -               rlun->rrpc = rrpc;
> -               rlun->parent = lun;
> -               INIT_LIST_HEAD(&rlun->prio_list);
> -               INIT_LIST_HEAD(&rlun->open_list);
> -               INIT_LIST_HEAD(&rlun->closed_list);
> -
> -               INIT_WORK(&rlun->ws_gc, rrpc_lun_gc);
> -               spin_lock_init(&rlun->lock);
> +               ret = rrpc_lun_init(rrpc, rlun, lun);
> +               if (ret)
> +                       goto err;
>
>                 rrpc->total_blocks += dev->blks_per_lun;
>                 rrpc->nr_pages += dev->sec_per_lun;
> -
> -               rlun->blocks = vzalloc(sizeof(struct rrpc_block) *
> -                                               rrpc->dev->blks_per_lun);
> -               if (!rlun->blocks)
> -                       goto err;
> -
> -               for (j = 0; j < rrpc->dev->blks_per_lun; j++) {
> -                       struct rrpc_block *rblk = &rlun->blocks[j];
> -                       struct nvm_block *blk = &lun->blocks[j];
> -
> -                       rblk->parent = blk;
> -                       rblk->rlun = rlun;
> -                       INIT_LIST_HEAD(&rblk->prio);
> -                       spin_lock_init(&rblk->lock);
> -               }
>         }
>
>         return 0;
>  err:
> -       return -ENOMEM;
> +       rrpc_luns_free(rrpc);
> +       return ret;
> +
>  }
>
>  /* returns 0 on success and stores the beginning address in *begin */
> @@ -1258,14 +1326,16 @@ static sector_t rrpc_capacity(void *private)
>  static void rrpc_block_map_update(struct rrpc *rrpc, struct rrpc_block
> *rblk)
>  {
>         struct nvm_dev *dev = rrpc->dev;
> +       struct rrpc_lun *rlun = rblk->rlun;
>         int offset;
>         struct rrpc_addr *laddr;
> -       u64 paddr, pladdr;
> +       u64 paddr, pladdr, poffset;
>
> +       poffset = lun_poffset(dev, rlun->parent);
>         for (offset = 0; offset < dev->pgs_per_blk; offset++) {
>                 paddr = block_to_addr(rrpc, rblk) + offset;
>
> -               pladdr = rrpc->rev_trans_map[paddr].addr;
> +               pladdr = rlun->rev_trans_map[paddr - poffset].addr;
>                 if (pladdr == ADDR_EMPTY)
>                         continue;
>
> @@ -1374,9 +1444,6 @@ static void *rrpc_init(struct nvm_dev *dev, struct
> gendisk *tdisk,
>                 goto err;
>         }
>
> -       rrpc->poffset = dev->sec_per_lun * lun_begin;
> -       rrpc->lun_offset = lun_begin;
> -
>         ret = rrpc_core_init(rrpc);
>         if (ret) {
>                 pr_err("nvm: rrpc: could not initialize core\n");
> diff --git a/drivers/lightnvm/rrpc.h b/drivers/lightnvm/rrpc.h
> index 9380c68..4d756d8 100644
> --- a/drivers/lightnvm/rrpc.h
> +++ b/drivers/lightnvm/rrpc.h
> @@ -86,6 +86,9 @@ struct rrpc_lun {
>                                          */
>
>         struct work_struct ws_gc;
> +       /* store a reverse map for garbage collection */
> +       struct rrpc_rev_addr *rev_trans_map;
> +       spinlock_t rev_lock;
>
>         spinlock_t lock;
>  };
> @@ -124,9 +127,6 @@ struct rrpc {
>          * addresses are used when writing to the disk block device.
>          */
>         struct rrpc_addr *trans_map;
> -       /* also store a reverse map for garbage collection */
> -       struct rrpc_rev_addr *rev_trans_map;
> -       spinlock_t rev_lock;
>
>         struct rrpc_inflight inflights;
>
> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
> index 18f1bb0..a33af4f 100644
> --- a/include/linux/lightnvm.h
> +++ b/include/linux/lightnvm.h
> @@ -271,6 +271,7 @@ struct nvm_lun {
>         spinlock_t lock;
>
>         struct nvm_block *blocks;
> +       void *private;
>  };
>
>  enum {
> @@ -342,6 +343,8 @@ struct nvm_dev {
>         int nr_luns;
>         unsigned max_pages_per_blk;
>
> +       unsigned long *lun_map;
> +
>         void *ppalist_pool;
>
>         struct nvm_id identity;
> @@ -462,6 +465,8 @@ typedef int (nvmm_submit_io_fn)(struct nvm_dev *,
> struct nvm_rq *);
>  typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *,
>                                                                 unsigned long);
>  typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int);
> +typedef int (nvmm_reserve_lun(struct nvm_dev *, int));
> +typedef void (nvmm_release_lun(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);
> @@ -488,6 +493,8 @@ struct nvmm_type {
>
>         /* Configuration management */
>         nvmm_get_lun_fn *get_lun;
> +       nvmm_reserve_lun *reserve_lun;
> +       nvmm_release_lun *release_lun;
>
>         /* Statistics */
>         nvmm_lun_info_print_fn *lun_info_print;
>

  reply	other threads:[~2016-01-28  8:50 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-26 12:33 [PATCH v2 1/2] lightnvm: specify target's logical address area Wenwei Tao
2016-01-26 12:33 ` [PATCH v2 2/2] lightnvm: add non-continuous lun target creation support Wenwei Tao
2016-01-27  9:44   ` Matias Bjørling
2016-01-28  8:50     ` Wenwei Tao [this message]
2016-01-28  9:09       ` Matias Bjørling
2016-01-28 10:19         ` Wenwei Tao
2016-01-26 14:52 ` [PATCH v2 1/2] lightnvm: specify target's logical address area Matias Bjørling
2016-01-27  2:21   ` Wenwei Tao
2016-01-27  5:52     ` Matias Bjørling
2016-01-27  6:06       ` Wenwei Tao
2016-01-27  9:36         ` Matias Bjørling
2016-01-27 12:47           ` Wenwei Tao
2016-01-27 13:26             ` Matias Bjørling
2016-01-27 14:58               ` Wenwei Tao
2016-01-27 19:46                 ` Matias Bjørling

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CACygaLC80YQir5w+XbZi=yvCL_+BozCok1wp1j6rJ2MTZqRF9Q@mail.gmail.com' \
    --to=ww.tao0320@gmail.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mb@lightnvm.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.