Re: [Yaffs] bad block management

Top Page
Attachments:
Message as email
+ (text/plain)
+ 0001-Add-block-refresh-handling-in-yaffs-core.patch (text/x-patch)
Delete this message
Reply to this message
Author: Charles Manning
Date:  
To: bpqw
CC: yaffs@lists.aleph1.co.uk
Subject: Re: [Yaffs] bad block management
Hello White Ding

Ok, I have put together a patch showing the changes for the yaffs
core. This is attached. I hope it works.

If you can make the patches for the mtd to issue
YAFFS_ECC_RESULT_REFRESH when required then you can send that to me
and we can hook it all up.

Regards Charles

On Thu, Aug 7, 2014 at 12:46 PM, bpqw <> wrote:
> Hi Charles,
> I am clear,
> Currently there is no YAFFS_ECC_RESULT_REFRESH, so we need to add this case and the threshold as you recommend should be (refresh_threshold + ecc_strength + 1) /2,
> I will plan to create a patch for this.
> Do you have any proposal?
>
> Br
> White Ding
> ____________________________
> EBU APAC Application Engineering
> Tel:86-21-38997078
> Mobile: 86-13761729112
> Address: No 601 Fasai Rd, Waigaoqiao Free Trade Zone Pudong, Shanghai, China
>
> -----Original Message-----
> From: Charles Manning [mailto:cdhmanning@gmail.com]
> Sent: Thursday, August 07, 2014 5:44 AM
> To: bpqw
> Cc:
> Subject: Re: [Yaffs] bad block management
>
> On Wed, Aug 6, 2014 at 7:26 PM, bpqw <> wrote:
>> Hi Clarles,
>> We recommended if the bitflip over threshold we just need to refresh the block but not retire it.
>> So we doubt is it reasonable just according to the bitflips over
>> mtd->bitflip_threshold over three times to judge the block as bad block?
>>
>
> Hello White Ding
>
> I certainly understand where you are coming from here.
>
> The concern this raises is that we then lose the safety net of retiring blocks before they go bad.
>
> What we really need is two thresholds in mtd: refresh only, refresh and apply retiring logic.
>
> I suppose we could use bitflip_threshold and bitflip_strength for those, or maybe something slightly different to give more margin.
> Unfortunately the threshold and strength are often set to be the same.
>
> So I would like to use something that can be made up called, say, retire_limit.
> Where
> retire_limit = (refresh_threshold + ecc_strength + 1) /2.
>
>
> For that to work Yaffs needs another level of ECC error.
>
> How about this:
> enum yaffs_ecc_result {
>     YAFFS_ECC_RESULT_UNKNOWN,
>     YAFFS_ECC_RESULT_NO_ERROR,
>     YAFFS_ECC_RESULT_REFRESH,
>     YAFFS_ECC_RESULT_FIXED,
>     YAFFS_ECC_RESULT_UNFIXED
> };

>
> Then we can have something like, say:
>
> if errors < bitflip_threshold --> NO_ERROR else if errors < retire_limit --> REFRESH else if not corrupted --> FIXED else --> UNFIXED
>
> So for a concrete example, let us say we have something where:
> ecc_strength = 8, bitflip_threshold = 4 then we would have retire_limit = 6
>
> So we would get the following behaviour:
>
> * 0 to 3 errors --> NO_ERROR
> * 4 to 5 errors --> REFRESH (refresh only)
> * 6 to 8 errors -->FIXED (refresh and increment chunk_error_strikes)
> * more than that --> UNFIXED.
>
> Does that make sense?
>
> Charles

From dba051c0183a6ce9f1af61f9ec2b0f09419e48da Mon Sep 17 00:00:00 2001
From: Charles Manning <>
Date: Thu, 7 Aug 2014 13:21:35 +1200
Subject: [PATCH] Add block refresh handling in yaffs core

THis still needs the drivers to cooperate.

Signed-off-by: Charles Manning <>
---
yaffs_guts.c | 17 ++++++++++++-----
yaffs_guts.h | 4 +++-
yaffs_nand.c | 2 +-
3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/yaffs_guts.c b/yaffs_guts.c
index 1c0ae71..35440d2 100644
--- a/yaffs_guts.c
+++ b/yaffs_guts.c
@@ -211,11 +211,18 @@ static void yaffs_handle_chunk_update(struct yaffs_dev *dev, int nand_chunk,
}

 void yaffs_handle_chunk_error(struct yaffs_dev *dev,
-                  struct yaffs_block_info *bi)
+                  struct yaffs_block_info *bi,
+                  enum yaffs_ecc_result err_type)
 {
-    if (!bi->gc_prioritise) {
-        bi->gc_prioritise = 1;
-        dev->has_pending_prioritised_gc = 1;
+    if (bi->gc_prioritise)
+        return;
+
+    /* We need to refresh this data by gc'ing the block soon. */
+    bi->gc_prioritise = 1;
+    dev->has_pending_prioritised_gc = 1;
+
+    /* If it was more than just refresh request then consider retirement. */
+    if (err_type > YAFFS_ECC_RESULT_REFRESH) {
         bi->chunk_error_strikes++;


         if (bi->chunk_error_strikes > 3) {
@@ -233,7 +240,7 @@ static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, int nand_chunk,
     int flash_block = nand_chunk / dev->param.chunks_per_block;
     struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block);


-    yaffs_handle_chunk_error(dev, bi);
+    yaffs_handle_chunk_error(dev, bi, YAFFS_ECC_RESULT_FIXED);


     if (erased_ok) {
         /* Was an actual write failure,
diff --git a/yaffs_guts.h b/yaffs_guts.h
index 231f8ac..397aae8 100644
--- a/yaffs_guts.h
+++ b/yaffs_guts.h
@@ -163,6 +163,7 @@ union yaffs_tags_union {
 enum yaffs_ecc_result {
     YAFFS_ECC_RESULT_UNKNOWN,
     YAFFS_ECC_RESULT_NO_ERROR,
+    YAFFS_ECC_RESULT_REFRESH,
     YAFFS_ECC_RESULT_FIXED,
     YAFFS_ECC_RESULT_UNFIXED
 };
@@ -940,7 +941,8 @@ void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash,
              int lyn);
 int yaffs_check_ff(u8 *buffer, int n_bytes);
 void yaffs_handle_chunk_error(struct yaffs_dev *dev,
-                  struct yaffs_block_info *bi);
+                  struct yaffs_block_info *bi,
+                  enum yaffs_ecc_result err_type);


 u8 *yaffs_get_temp_buffer(struct yaffs_dev *dev);
 void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer);
diff --git a/yaffs_nand.c b/yaffs_nand.c
index 0d8499b..a8dae40 100644
--- a/yaffs_nand.c
+++ b/yaffs_nand.c
@@ -42,7 +42,7 @@ int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
         bi = yaffs_get_block_info(dev,
                       nand_chunk /
                       dev->param.chunks_per_block);
-        yaffs_handle_chunk_error(dev, bi);
+        yaffs_handle_chunk_error(dev, bi, tags->ecc_result);
     }
     return result;
 }
-- 
1.9.1