> On 5 Mar 2019, at 14.51, Igor Konopko <igor.j.konopko@xxxxxxxxx> wrote: > > When we creating pblk instance with factory flag, there is a > possibility that some chunks are in open state, which does not allow > to issue erase request to them directly, based on OCSSD 2.0 spec. > Still most of the controllers allows for such a transition, but it is > not guaranteed that the particular drive will do so. This patch adds > the proper warning during pblk factory creation to let user know about > number of chunks in such a state, which can potentially be a reason > of erase failures. > > Signed-off-by: Igor Konopko <igor.j.konopko@xxxxxxxxx> > --- > drivers/lightnvm/pblk-core.c | 14 ++++++++++++++ > drivers/lightnvm/pblk-init.c | 14 +++++++++++--- > drivers/lightnvm/pblk.h | 1 + > 3 files changed, 26 insertions(+), 3 deletions(-) > > diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c > index 64280e6..4f16596 100644 > --- a/drivers/lightnvm/pblk-core.c > +++ b/drivers/lightnvm/pblk-core.c > @@ -161,6 +161,20 @@ struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk, > return meta + ch_off + lun_off + chk_off; > } > > +int pblk_count_opened_chunks(struct pblk *pblk, struct nvm_chk_meta *meta) > +{ > + struct nvm_tgt_dev *dev = pblk->dev; > + struct nvm_geo *geo = &dev->geo; > + int i, cnt = 0; > + > + for (i = 0; i < geo->all_luns; i++) { > + if (meta[i].state == NVM_CHK_ST_OPEN) > + cnt++; > + } > + > + return cnt; > +} > + > void __pblk_map_invalidate(struct pblk *pblk, struct pblk_line *line, > u64 paddr) > { > diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c > index 97b4c6e..f590f62 100644 > --- a/drivers/lightnvm/pblk-init.c > +++ b/drivers/lightnvm/pblk-init.c > @@ -1028,12 +1028,12 @@ static int pblk_line_meta_init(struct pblk *pblk) > return 0; > } > > -static int pblk_lines_init(struct pblk *pblk) > +static int pblk_lines_init(struct pblk *pblk, bool factory_init) > { > struct pblk_line_mgmt *l_mg = &pblk->l_mg; > struct pblk_line *line; > void *chunk_meta; > - int nr_free_chks = 0; > + int nr_free_chks = 0, nr_opened_chks; > int i, ret; > > ret = pblk_line_meta_init(pblk); > @@ -1054,6 +1054,14 @@ static int pblk_lines_init(struct pblk *pblk) > goto fail_free_luns; > } > > + if (factory_init) { > + nr_opened_chks = pblk_count_opened_chunks(pblk, chunk_meta); > + if (nr_opened_chks) { > + pblk_warn(pblk, "There are %d opened chunks\n", > + nr_opened_chks); > + } > + } > + > pblk->lines = kcalloc(l_mg->nr_lines, sizeof(struct pblk_line), > GFP_KERNEL); > if (!pblk->lines) { > @@ -1245,7 +1253,7 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk, > goto fail; > } > > - ret = pblk_lines_init(pblk); > + ret = pblk_lines_init(pblk, flags & NVM_TARGET_FACTORY); > if (ret) { > pblk_err(pblk, "could not initialize lines\n"); > goto fail_free_core; > diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h > index 6c82776..c2f07ec 100644 > --- a/drivers/lightnvm/pblk.h > +++ b/drivers/lightnvm/pblk.h > @@ -795,6 +795,7 @@ struct nvm_chk_meta *pblk_get_chunk_meta(struct pblk *pblk); > struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk, > struct nvm_chk_meta *lp, > struct ppa_addr ppa); > +int pblk_count_opened_chunks(struct pblk *pblk, struct nvm_chk_meta *_meta); > void pblk_log_write_err(struct pblk *pblk, struct nvm_rq *rqd); > void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd); > int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd); > -- > 2.9.5 I think the warning is a good tradeoff. If you want to avoid looping again across all chunks, note that we are already doing this in pblk_setup_line_meta_chk(). It should be easy to refactor it, check here for NVM_CHK_ST_OPEN and then return the counter.
Attachment:
signature.asc
Description: Message signed with OpenPGP