Message ID | 1454585687-4720-2-git-send-email-ww.tao0320@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 02/04/2016 12:34 PM, Wenwei Tao wrote: > Add a bitmap of luns to indicate the status > of luns: inuse/available. When create targets > do the necessary check to avoid allocating luns > that are already allocated. > > Signed-off-by: Wenwei Tao <ww.tao0320@gmail.com> > --- > drivers/lightnvm/core.c | 5 ++++ > drivers/lightnvm/gennvm.c | 18 +++++++++++++++ > drivers/lightnvm/rrpc.c | 59 +++++++++++++++++++++++++++++++++++------------ > include/linux/lightnvm.h | 5 ++++ > 4 files changed, 72 insertions(+), 15 deletions(-) > > diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c > index 93c035b..11b8e2d 100644 > --- a/drivers/lightnvm/core.c > +++ b/drivers/lightnvm/core.c > @@ -464,6 +464,10 @@ static int nvm_core_init(struct nvm_dev *dev) > dev->nr_luns = dev->luns_per_chnl * dev->nr_chnls; > > dev->total_secs = dev->nr_luns * dev->sec_per_lun; > + 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); > @@ -606,6 +610,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 fba3fbd..adc10c2 100644 > --- a/drivers/lightnvm/gennvm.c > +++ b/drivers/lightnvm/gennvm.c > @@ -190,6 +190,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)]; > @@ -480,10 +483,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; > } > > @@ -525,6 +541,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 6ce5f73..2bd5789 100644 > --- a/drivers/lightnvm/rrpc.c > +++ b/drivers/lightnvm/rrpc.c > @@ -1128,6 +1128,22 @@ static void rrpc_core_free(struct rrpc *rrpc) > > static void rrpc_luns_free(struct rrpc *rrpc) > { > + struct nvm_dev *dev = rrpc->dev; > + struct nvm_lun *lun; > + struct rrpc_lun *rlun; > + int i; > + > + if (!rrpc->luns) > + return; > + > + for (i = 0; i < rrpc->nr_luns; i++) { > + rlun = &rrpc->luns[i]; > + lun = rlun->parent; > + if (!lun) > + break; > + dev->mt->release_lun(dev, lun->id); > + vfree(rlun->blocks); > + } > kfree(rrpc->luns); > } > > @@ -1135,7 +1151,7 @@ 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, j, ret = -EINVAL; > > if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) { > pr_err("rrpc: number of pages per block too high."); > @@ -1151,25 +1167,26 @@ 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; > > - 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); > + if (dev->mt->reserve_lun(dev, lunid)) { > + pr_err("rrpc: lun %u is already allocated\n", lunid); > + goto err; > + } > > - rrpc->total_blocks += dev->blks_per_lun; > - rrpc->nr_sects += dev->sec_per_lun; > + lun = dev->mt->get_lun(dev, lunid); > + if (!lun) > + goto err; > > + rlun = &rrpc->luns[i]; > + rlun->parent = lun; > rlun->blocks = vzalloc(sizeof(struct rrpc_block) * > rrpc->dev->blks_per_lun); > - if (!rlun->blocks) > + if (!rlun->blocks) { > + ret = -ENOMEM; > goto err; > + } > > for (j = 0; j < rrpc->dev->blks_per_lun; j++) { > struct rrpc_block *rblk = &rlun->blocks[j]; > @@ -1180,11 +1197,23 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) > INIT_LIST_HEAD(&rblk->prio); > spin_lock_init(&rblk->lock); > } > + > + rlun->rrpc = rrpc; > + 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); > + > + rrpc->total_blocks += dev->blks_per_lun; > + rrpc->nr_sects += dev->sec_per_lun; > + > } > > return 0; > err: > - return -ENOMEM; > + return ret; > } > > /* returns 0 on success and stores the beginning address in *begin */ > diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h > index ce58ad5..2a17dc1 100644 > --- a/include/linux/lightnvm.h > +++ b/include/linux/lightnvm.h > @@ -342,6 +342,7 @@ struct nvm_dev { > int nr_luns; > unsigned max_pages_per_blk; > > + unsigned long *lun_map; > void *ppalist_pool; > > struct nvm_id identity; > @@ -462,6 +463,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 +491,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; > Thanks, applied for 4.6. I added an extra kfree(dev->lun_map) at the end of nvm_core_init to make sure that we freed the lun_map if other allocations fails in initialization. -- To unsubscribe from this list: send the line "unsubscribe linux-block" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Forgot to do that. Thanks for fixing my mistake. 2016-02-05 19:59 GMT+08:00 Matias Bjørling <mb@lightnvm.io>: > On 02/04/2016 12:34 PM, Wenwei Tao wrote: >> Add a bitmap of luns to indicate the status >> of luns: inuse/available. When create targets >> do the necessary check to avoid allocating luns >> that are already allocated. >> >> Signed-off-by: Wenwei Tao <ww.tao0320@gmail.com> >> --- >> drivers/lightnvm/core.c | 5 ++++ >> drivers/lightnvm/gennvm.c | 18 +++++++++++++++ >> drivers/lightnvm/rrpc.c | 59 +++++++++++++++++++++++++++++++++++------------ >> include/linux/lightnvm.h | 5 ++++ >> 4 files changed, 72 insertions(+), 15 deletions(-) >> >> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c >> index 93c035b..11b8e2d 100644 >> --- a/drivers/lightnvm/core.c >> +++ b/drivers/lightnvm/core.c >> @@ -464,6 +464,10 @@ static int nvm_core_init(struct nvm_dev *dev) >> dev->nr_luns = dev->luns_per_chnl * dev->nr_chnls; >> >> dev->total_secs = dev->nr_luns * dev->sec_per_lun; >> + 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); >> @@ -606,6 +610,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 fba3fbd..adc10c2 100644 >> --- a/drivers/lightnvm/gennvm.c >> +++ b/drivers/lightnvm/gennvm.c >> @@ -190,6 +190,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)]; >> @@ -480,10 +483,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; >> } >> >> @@ -525,6 +541,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 6ce5f73..2bd5789 100644 >> --- a/drivers/lightnvm/rrpc.c >> +++ b/drivers/lightnvm/rrpc.c >> @@ -1128,6 +1128,22 @@ static void rrpc_core_free(struct rrpc *rrpc) >> >> static void rrpc_luns_free(struct rrpc *rrpc) >> { >> + struct nvm_dev *dev = rrpc->dev; >> + struct nvm_lun *lun; >> + struct rrpc_lun *rlun; >> + int i; >> + >> + if (!rrpc->luns) >> + return; >> + >> + for (i = 0; i < rrpc->nr_luns; i++) { >> + rlun = &rrpc->luns[i]; >> + lun = rlun->parent; >> + if (!lun) >> + break; >> + dev->mt->release_lun(dev, lun->id); >> + vfree(rlun->blocks); >> + } >> kfree(rrpc->luns); >> } >> >> @@ -1135,7 +1151,7 @@ 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, j, ret = -EINVAL; >> >> if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) { >> pr_err("rrpc: number of pages per block too high."); >> @@ -1151,25 +1167,26 @@ 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; >> >> - 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); >> + if (dev->mt->reserve_lun(dev, lunid)) { >> + pr_err("rrpc: lun %u is already allocated\n", lunid); >> + goto err; >> + } >> >> - rrpc->total_blocks += dev->blks_per_lun; >> - rrpc->nr_sects += dev->sec_per_lun; >> + lun = dev->mt->get_lun(dev, lunid); >> + if (!lun) >> + goto err; >> >> + rlun = &rrpc->luns[i]; >> + rlun->parent = lun; >> rlun->blocks = vzalloc(sizeof(struct rrpc_block) * >> rrpc->dev->blks_per_lun); >> - if (!rlun->blocks) >> + if (!rlun->blocks) { >> + ret = -ENOMEM; >> goto err; >> + } >> >> for (j = 0; j < rrpc->dev->blks_per_lun; j++) { >> struct rrpc_block *rblk = &rlun->blocks[j]; >> @@ -1180,11 +1197,23 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) >> INIT_LIST_HEAD(&rblk->prio); >> spin_lock_init(&rblk->lock); >> } >> + >> + rlun->rrpc = rrpc; >> + 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); >> + >> + rrpc->total_blocks += dev->blks_per_lun; >> + rrpc->nr_sects += dev->sec_per_lun; >> + >> } >> >> return 0; >> err: >> - return -ENOMEM; >> + return ret; >> } >> >> /* returns 0 on success and stores the beginning address in *begin */ >> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h >> index ce58ad5..2a17dc1 100644 >> --- a/include/linux/lightnvm.h >> +++ b/include/linux/lightnvm.h >> @@ -342,6 +342,7 @@ struct nvm_dev { >> int nr_luns; >> unsigned max_pages_per_blk; >> >> + unsigned long *lun_map; >> void *ppalist_pool; >> >> struct nvm_id identity; >> @@ -462,6 +463,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 +491,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; >> > Thanks, applied for 4.6. I added an extra kfree(dev->lun_map) at the end > of nvm_core_init to make sure that we freed the lun_map if other > allocations fails in initialization. -- To unsubscribe from this list: send the line "unsubscribe linux-block" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 02/05/2016 01:23 PM, Wenwei Tao wrote: > Forgot to do that. > Thanks for fixing my mistake. No worries, you fixed a couple that I introduced ;) -- To unsubscribe from this list: send the line "unsubscribe linux-block" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 93c035b..11b8e2d 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -464,6 +464,10 @@ static int nvm_core_init(struct nvm_dev *dev) dev->nr_luns = dev->luns_per_chnl * dev->nr_chnls; dev->total_secs = dev->nr_luns * dev->sec_per_lun; + 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); @@ -606,6 +610,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 fba3fbd..adc10c2 100644 --- a/drivers/lightnvm/gennvm.c +++ b/drivers/lightnvm/gennvm.c @@ -190,6 +190,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)]; @@ -480,10 +483,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; } @@ -525,6 +541,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 6ce5f73..2bd5789 100644 --- a/drivers/lightnvm/rrpc.c +++ b/drivers/lightnvm/rrpc.c @@ -1128,6 +1128,22 @@ static void rrpc_core_free(struct rrpc *rrpc) static void rrpc_luns_free(struct rrpc *rrpc) { + struct nvm_dev *dev = rrpc->dev; + struct nvm_lun *lun; + struct rrpc_lun *rlun; + int i; + + if (!rrpc->luns) + return; + + for (i = 0; i < rrpc->nr_luns; i++) { + rlun = &rrpc->luns[i]; + lun = rlun->parent; + if (!lun) + break; + dev->mt->release_lun(dev, lun->id); + vfree(rlun->blocks); + } kfree(rrpc->luns); } @@ -1135,7 +1151,7 @@ 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, j, ret = -EINVAL; if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) { pr_err("rrpc: number of pages per block too high."); @@ -1151,25 +1167,26 @@ 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; - 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); + if (dev->mt->reserve_lun(dev, lunid)) { + pr_err("rrpc: lun %u is already allocated\n", lunid); + goto err; + } - rrpc->total_blocks += dev->blks_per_lun; - rrpc->nr_sects += dev->sec_per_lun; + lun = dev->mt->get_lun(dev, lunid); + if (!lun) + goto err; + rlun = &rrpc->luns[i]; + rlun->parent = lun; rlun->blocks = vzalloc(sizeof(struct rrpc_block) * rrpc->dev->blks_per_lun); - if (!rlun->blocks) + if (!rlun->blocks) { + ret = -ENOMEM; goto err; + } for (j = 0; j < rrpc->dev->blks_per_lun; j++) { struct rrpc_block *rblk = &rlun->blocks[j]; @@ -1180,11 +1197,23 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) INIT_LIST_HEAD(&rblk->prio); spin_lock_init(&rblk->lock); } + + rlun->rrpc = rrpc; + 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); + + rrpc->total_blocks += dev->blks_per_lun; + rrpc->nr_sects += dev->sec_per_lun; + } return 0; err: - return -ENOMEM; + return ret; } /* returns 0 on success and stores the beginning address in *begin */ diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index ce58ad5..2a17dc1 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h @@ -342,6 +342,7 @@ struct nvm_dev { int nr_luns; unsigned max_pages_per_blk; + unsigned long *lun_map; void *ppalist_pool; struct nvm_id identity; @@ -462,6 +463,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 +491,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;
Add a bitmap of luns to indicate the status of luns: inuse/available. When create targets do the necessary check to avoid allocating luns that are already allocated. Signed-off-by: Wenwei Tao <ww.tao0320@gmail.com> --- drivers/lightnvm/core.c | 5 ++++ drivers/lightnvm/gennvm.c | 18 +++++++++++++++ drivers/lightnvm/rrpc.c | 59 +++++++++++++++++++++++++++++++++++------------ include/linux/lightnvm.h | 5 ++++ 4 files changed, 72 insertions(+), 15 deletions(-)