Message ID | 20190322144843.9602-15-igor.j.konopko@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | lightnvm: next set of improvements for 5.2 | expand |
On 3/22/19 3:48 PM, Igor Konopko wrote: > Currently when there is an IO error (or similar) on GC read path, pblk > still moves this line to free state What those "this" line refer to? , what leads to data mismatch issue. what -> which leads to a data mismatch. > > This patch adds a handling for such an error - after that changes this > line will be returned to closed state so it can be still in use > for reading - at least we will be able to return error status to user > when user tries to read such a data. Could you update the description. It is hard for me to parse. > > Signed-off-by: Igor Konopko <igor.j.konopko@intel.com> > Reviewed-by: Javier González <javier@javigon.com> > Reviewed-by: Hans Holmberg <hans.holmberg@cnexlabs.com> > --- > drivers/lightnvm/pblk-core.c | 8 ++++++++ > drivers/lightnvm/pblk-gc.c | 5 ++--- > drivers/lightnvm/pblk-read.c | 1 - > drivers/lightnvm/pblk.h | 2 ++ > 4 files changed, 12 insertions(+), 4 deletions(-) > > diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c > index 9d9a9e2..1b88e5e 100644 > --- a/drivers/lightnvm/pblk-core.c > +++ b/drivers/lightnvm/pblk-core.c > @@ -1799,6 +1799,14 @@ static void __pblk_line_put(struct pblk *pblk, struct pblk_line *line) > > spin_lock(&line->lock); > WARN_ON(line->state != PBLK_LINESTATE_GC); > + if (line->w_err_gc->has_gc_err) { > + spin_unlock(&line->lock); > + pblk_err(pblk, "line %d had errors during GC\n", line->id); > + pblk_put_line_back(pblk, line); > + line->w_err_gc->has_gc_err = 0; > + return; > + } > + > line->state = PBLK_LINESTATE_FREE; > trace_pblk_line_state(pblk_disk_name(pblk), line->id, > line->state); > diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c > index e23b192..63ee205 100644 > --- a/drivers/lightnvm/pblk-gc.c > +++ b/drivers/lightnvm/pblk-gc.c > @@ -59,7 +59,7 @@ static void pblk_gc_writer_kick(struct pblk_gc *gc) > wake_up_process(gc->gc_writer_ts); > } > > -static void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line) > +void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line) > { > struct pblk_line_mgmt *l_mg = &pblk->l_mg; > struct list_head *move_list; > @@ -98,8 +98,7 @@ static void pblk_gc_line_ws(struct work_struct *work) > /* Read from GC victim block */ > ret = pblk_submit_read_gc(pblk, gc_rq); > if (ret) { > - pblk_err(pblk, "failed GC read in line:%d (err:%d)\n", > - line->id, ret); > + line->w_err_gc->has_gc_err = 1; > goto out; > } > > diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c > index 264d1d7..5481dfa 100644 > --- a/drivers/lightnvm/pblk-read.c > +++ b/drivers/lightnvm/pblk-read.c > @@ -494,7 +494,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq) > > if (pblk_submit_io_sync(pblk, &rqd)) { > ret = -EIO; > - pblk_err(pblk, "GC read request failed\n"); > goto err_free_bio; > } > > diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h > index 0999245..0bc4255 100644 > --- a/drivers/lightnvm/pblk.h > +++ b/drivers/lightnvm/pblk.h > @@ -425,6 +425,7 @@ struct pblk_smeta { > > struct pblk_w_err_gc { > int has_write_err; > + int has_gc_err; > __le64 *lba_list; > }; > > @@ -916,6 +917,7 @@ void pblk_gc_free_full_lines(struct pblk *pblk); > void pblk_gc_sysfs_state_show(struct pblk *pblk, int *gc_enabled, > int *gc_active); > int pblk_gc_sysfs_force(struct pblk *pblk, int force); > +void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line); > > /* > * pblk rate limiter >
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c index 9d9a9e2..1b88e5e 100644 --- a/drivers/lightnvm/pblk-core.c +++ b/drivers/lightnvm/pblk-core.c @@ -1799,6 +1799,14 @@ static void __pblk_line_put(struct pblk *pblk, struct pblk_line *line) spin_lock(&line->lock); WARN_ON(line->state != PBLK_LINESTATE_GC); + if (line->w_err_gc->has_gc_err) { + spin_unlock(&line->lock); + pblk_err(pblk, "line %d had errors during GC\n", line->id); + pblk_put_line_back(pblk, line); + line->w_err_gc->has_gc_err = 0; + return; + } + line->state = PBLK_LINESTATE_FREE; trace_pblk_line_state(pblk_disk_name(pblk), line->id, line->state); diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c index e23b192..63ee205 100644 --- a/drivers/lightnvm/pblk-gc.c +++ b/drivers/lightnvm/pblk-gc.c @@ -59,7 +59,7 @@ static void pblk_gc_writer_kick(struct pblk_gc *gc) wake_up_process(gc->gc_writer_ts); } -static void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line) +void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line) { struct pblk_line_mgmt *l_mg = &pblk->l_mg; struct list_head *move_list; @@ -98,8 +98,7 @@ static void pblk_gc_line_ws(struct work_struct *work) /* Read from GC victim block */ ret = pblk_submit_read_gc(pblk, gc_rq); if (ret) { - pblk_err(pblk, "failed GC read in line:%d (err:%d)\n", - line->id, ret); + line->w_err_gc->has_gc_err = 1; goto out; } diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c index 264d1d7..5481dfa 100644 --- a/drivers/lightnvm/pblk-read.c +++ b/drivers/lightnvm/pblk-read.c @@ -494,7 +494,6 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq) if (pblk_submit_io_sync(pblk, &rqd)) { ret = -EIO; - pblk_err(pblk, "GC read request failed\n"); goto err_free_bio; } diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h index 0999245..0bc4255 100644 --- a/drivers/lightnvm/pblk.h +++ b/drivers/lightnvm/pblk.h @@ -425,6 +425,7 @@ struct pblk_smeta { struct pblk_w_err_gc { int has_write_err; + int has_gc_err; __le64 *lba_list; }; @@ -916,6 +917,7 @@ void pblk_gc_free_full_lines(struct pblk *pblk); void pblk_gc_sysfs_state_show(struct pblk *pblk, int *gc_enabled, int *gc_active); int pblk_gc_sysfs_force(struct pblk *pblk, int force); +void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line); /* * pblk rate limiter