diff mbox series

[11/18] lightnvm: pblk: fix update line wp in OOB recovery

Message ID 20190314160428.3559-12-igor.j.konopko@intel.com (mailing list archive)
State New, archived
Headers show
Series lightnvm: next set of improvements for 5.2 | expand

Commit Message

Igor Konopko March 14, 2019, 4:04 p.m. UTC
In case of OOB recovery, we can hit the scenario when all the data in
line were written and some part of emeta was written too. In such
a case pblk_update_line_wp() function will call pblk_alloc_page()
function which will case to set left_msecs to value below zero
(since this field does not track emeta region) and thus will lead to
multiple kernel warnings. This patch fixes that issue.

Signed-off-by: Igor Konopko <igor.j.konopko@intel.com>
---
 drivers/lightnvm/pblk-recovery.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

Comments

Javier González March 18, 2019, 6:56 a.m. UTC | #1
> On 14 Mar 2019, at 17.04, Igor Konopko <igor.j.konopko@intel.com> wrote:
> 
> In case of OOB recovery, we can hit the scenario when all the data in
> line were written and some part of emeta was written too. In such
> a case pblk_update_line_wp() function will call pblk_alloc_page()
> function which will case to set left_msecs to value below zero
> (since this field does not track emeta region) and thus will lead to
> multiple kernel warnings. This patch fixes that issue.
> 
> Signed-off-by: Igor Konopko <igor.j.konopko@intel.com>
> ---
> drivers/lightnvm/pblk-recovery.c | 20 +++++++++++++++++---
> 1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
> index 73d5ead..4764596 100644
> --- a/drivers/lightnvm/pblk-recovery.c
> +++ b/drivers/lightnvm/pblk-recovery.c
> @@ -93,10 +93,24 @@ static int pblk_recov_l2p_from_emeta(struct pblk *pblk, struct pblk_line *line)
> static void pblk_update_line_wp(struct pblk *pblk, struct pblk_line *line,
> 				u64 written_secs)
> {
> -	int i;
> +	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
> +	int i = 0;
> 
> -	for (i = 0; i < written_secs; i += pblk->min_write_pgs)
> -		pblk_alloc_page(pblk, line, pblk->min_write_pgs);
> +	for (; i < written_secs; i += pblk->min_write_pgs)

Why no i = 0 here?

> +		__pblk_alloc_page(pblk, line, pblk->min_write_pgs);
> +
> +	spin_lock(&l_mg->free_lock);
> +	if (written_secs > line->left_msecs) {
> +		/*
> +		 * We have all data sectors written
> +		 * and some emeta sectors written too.
> +		 */
> +		line->left_msecs = 0;
> +	} else {
> +		/* We have only some data sectors written. */
> +		line->left_msecs -= written_secs;
> +	}
> +	spin_unlock(&l_mg->free_lock);
> }
> 
> static u64 pblk_sec_in_open_line(struct pblk *pblk, struct pblk_line *line)
> --
> 2.9.5

Otherwise, it looks good.

Reviewed-by: Javier González <javier@javigon.com>
Igor Konopko March 18, 2019, 1:06 p.m. UTC | #2
On 18.03.2019 07:56, Javier González wrote:
>> On 14 Mar 2019, at 17.04, Igor Konopko <igor.j.konopko@intel.com> wrote:
>>
>> In case of OOB recovery, we can hit the scenario when all the data in
>> line were written and some part of emeta was written too. In such
>> a case pblk_update_line_wp() function will call pblk_alloc_page()
>> function which will case to set left_msecs to value below zero
>> (since this field does not track emeta region) and thus will lead to
>> multiple kernel warnings. This patch fixes that issue.
>>
>> Signed-off-by: Igor Konopko <igor.j.konopko@intel.com>
>> ---
>> drivers/lightnvm/pblk-recovery.c | 20 +++++++++++++++++---
>> 1 file changed, 17 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
>> index 73d5ead..4764596 100644
>> --- a/drivers/lightnvm/pblk-recovery.c
>> +++ b/drivers/lightnvm/pblk-recovery.c
>> @@ -93,10 +93,24 @@ static int pblk_recov_l2p_from_emeta(struct pblk *pblk, struct pblk_line *line)
>> static void pblk_update_line_wp(struct pblk *pblk, struct pblk_line *line,
>> 				u64 written_secs)
>> {
>> -	int i;
>> +	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
>> +	int i = 0;
>>
>> -	for (i = 0; i < written_secs; i += pblk->min_write_pgs)
>> -		pblk_alloc_page(pblk, line, pblk->min_write_pgs);
>> +	for (; i < written_secs; i += pblk->min_write_pgs)
> 
> Why no i = 0 here?

Accidentally changed - will revert it.

> 
>> +		__pblk_alloc_page(pblk, line, pblk->min_write_pgs);
>> +
>> +	spin_lock(&l_mg->free_lock);
>> +	if (written_secs > line->left_msecs) {
>> +		/*
>> +		 * We have all data sectors written
>> +		 * and some emeta sectors written too.
>> +		 */
>> +		line->left_msecs = 0;
>> +	} else {
>> +		/* We have only some data sectors written. */
>> +		line->left_msecs -= written_secs;
>> +	}
>> +	spin_unlock(&l_mg->free_lock);
>> }
>>
>> static u64 pblk_sec_in_open_line(struct pblk *pblk, struct pblk_line *line)
>> --
>> 2.9.5
> 
> Otherwise, it looks good.
> 
> Reviewed-by: Javier González <javier@javigon.com>
> 
> 
>
diff mbox series

Patch

diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
index 73d5ead..4764596 100644
--- a/drivers/lightnvm/pblk-recovery.c
+++ b/drivers/lightnvm/pblk-recovery.c
@@ -93,10 +93,24 @@  static int pblk_recov_l2p_from_emeta(struct pblk *pblk, struct pblk_line *line)
 static void pblk_update_line_wp(struct pblk *pblk, struct pblk_line *line,
 				u64 written_secs)
 {
-	int i;
+	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
+	int i = 0;
 
-	for (i = 0; i < written_secs; i += pblk->min_write_pgs)
-		pblk_alloc_page(pblk, line, pblk->min_write_pgs);
+	for (; i < written_secs; i += pblk->min_write_pgs)
+		__pblk_alloc_page(pblk, line, pblk->min_write_pgs);
+
+	spin_lock(&l_mg->free_lock);
+	if (written_secs > line->left_msecs) {
+		/*
+		 * We have all data sectors written
+		 * and some emeta sectors written too.
+		 */
+		line->left_msecs = 0;
+	} else {
+		/* We have only some data sectors written. */
+		line->left_msecs -= written_secs;
+	}
+	spin_unlock(&l_mg->free_lock);
 }
 
 static u64 pblk_sec_in_open_line(struct pblk *pblk, struct pblk_line *line)