Hello Peter
On Tuesday 17 January 2012 08:13:21 Peter Barada wrote:
> I need to modify YAFFS to trigger garbage collection on a block that has
> too many page reads between erases.
>
> This is due to the characterisation of the Micron NAND
> (MTMT29C4G48MAPLCJI6) I'm using where it can only have ~20K reads
> between erasures to maintain UBER below 10E-14. The NAND itself has an
> internal 4-bit ECC engine, but I can't extract any useful information
> from the ECC due to the lack of bit error counts (i.e. the chip can only
> tell me that a read required some level of correction but not the amount
> of correction, and worse the rate of corrections indicated by the chip
> is too high to employ effective strike counting).
Oh how these silicon vendors seem to take glee in causing us pain!
>
> So I need to track the page reads in a block and if they reach a limit
> then cause the block to be garbage collected (i.e. copy out all the
> useful data and erase the block).
You just need to run the block through the garbage collector.
But first the block needs to be in FULL state. Now that is most likely the
case, but it is possible to contrive some cases where this might not be (eg.
write a couple of pages then read just those pages a million times).
That can be achieved by some code in the spirit of
if(block state == ALLOCATING)
yaffs_skip_rest_of_block(dev);
2. Then I think it will be ok to just call yaffs_gc_block() while locked.
yaffs_gc_block(dev, block_i_want_to_refresh, 1);
-or- cleverer
Or you could just set dev->gc_block = block_i_want_to_refresh and the garbage
collector will pick it up and sort it out in the next gc.
Of course that has the potential problem of two blocks needing refreshing and
one interrupting the other.
Perhaps the two ideas can be melded as follows:
if(block state == ALLOCATING)
yaffs_skip_rest_of_block(dev);
if(dev->gc_block)
yaffs_gc_block(dev, block_i_want_to_refresh, 1);
else
dev->gc_block = block_i_want_to_refesh;
- or - cleverist
Add a list of blocks needing refresh to dev and in yaffs_check_gc() add a new
clause for getting a new gc block
if (dev->gc_block < 1 && refresh list not empty) {
dev->gc_block = grab first in list;
dev->gc_chunk = 0;
dev->n_clean_ups = 0;
}
> Any help is appreciated!
Hope that helps....
Charles