[Yaffs] Some clarifications of AUTOPLACE with mtd & YAFFS2

Charles Manning manningc2 at actrix.gen.nz
Mon Oct 17 23:35:36 BST 2005


Hi all

I would like to let the vitriol of the last few week or so slide, but a lot of 
it contained some technical content that was wrong and thus I'd like to 
straighten out a few points on YAFFS2 and AUTOPLACE, hopefully in a 
reasonably coherent fashion.

Three main assertions that have been made are wrong:
1) mtd interfaces are "golden" and cannot be changed. Thus YAFFS must go 
through any required tricks to make a working solution.
2) That it is both possible and wise to attempt this.
3) I have not a clue what AUTOPLACE is all about and how it should work.

Below I make some comments on what Thomas has done. I am not levelling blame 
at him. He is a very busy man and works to a set of priorities that are not 
always what everyone else wants (besides, it is all open source so someone 
else could also jump in and fix ;-)). I have the highest regard for Thomas' 
knowledge and work.


A POTTED HISTORY OF THE AUTOPLACE NAND INTERFACE

Those that have been around YAFFS a long time will remember the original 
integration problems because YAFFS wanted to see things that mtd was not 
making available, in particular the oob info. To get this working, the first 
releases of YAFFS needed mtd patches to work. At that time, mtd nand support 
was very early days and soon the patch was no longer required as the mtd 
layer came up to speed (damn good effort from Thomas).

YAFFS1 is designed for Smartmedia data layout and thus there are the 
hard-wired yaffs_Spare structures etc. Thus, when more, and different flash 
layouts were introduces, things like the oob_sel were introduced to allow the 
generic nand code to work with various byte-layouts and ECC mechanisms.  
oob_sel has also changed  a few rimes. YAFFS1 suffered some minor traumas due 
to this, but nothing too bad. 

When I started designing YAFFS2, about 2.5 years ago now, one of the main 
goals was to be able to support a much wider range of NAND devices and work 
with different hardware ecc etc.  So, one of the first areas that was 
designed was the NAND interface. Clearly fixed binary structures would not 
work properly and a level of abstraction was required. This drove the move 
from yaffs_Spare to yaffs_ExtendedTags and the packed tags mechanisms.

As things slowly unfolded, I realised that it would be a better thing to get 
buy-in from Thomas sooner, rather than layer, as to how to progress 2k and 
other support in mtd. It is far better to get a sensible interface in place 
earlier than try to retro-fit  things later. As YAFFS is a customer to those 
interfaces, it made sense to get involved and discuss things. So in late 
2003, Thomas and I started some discussions on this subject. [Much of the 
discussion was on IRC, and some was email. I deleted some of my old email, 
but I still have some stuff I sent in October 2003]. My starting point was a 
more abstract NAND interface that did not require any knowledge of actual 
byte placement. [See below for a technical outline of the rationale]. Thomas, 
being a very knowledgeable fellow, also brought along a bunch ideas - many of 
them on the same wavelength.  The results of all this were a definition of 
the functionality, but not an absolute function call definition, of AUTOPLACE 
and abstract bad block handling.

I then continued with YAFFS2 development, outside of Linux, and a YAFFS2 
prototype was being stress tested by Christmas 2003. In January it was being 
stress tested on large arrays of 2k page NAND. Note that this was a stripped 
YAFFS1 and did not support simultaneous yaffs1/2 functionality or yaffs1 
compatability.

In approx April 2004, Thomas started working on the AUTOPLACE and bad block 
handling. IIRC, this was all in place by the end of May. 

I then set about retooling yaffs2 to support both yaffs2 and yaffs1 formats 
through a backward compatability layer (tags compatability) - in essence a 
fusion of both the YAFFS1 and YAFFS2 prototype. This effort got somewhat 
delayed by me taking some time off from YAFFS for personal reasons.

When I started checking out the YAFFS2<->mtd interfacing I used a small ram 
emulation driver that I hacked up quickly. This conformed to the interface 
that Thomas and I agreed on.

Then YAFFS2 was released on the world. A few people picked it up and started 
playing. There were a few things that were patched that fixed some of the 
fusion problems (eg. Nick Ban'es patches for compatability mode).  
Unfortunately it takes time before people switch over and start testing with 
the 2k page devices. Some of the bugs discovered were due to some problems in 
the mtd not doing the AUTOPLACE properly (!!shock! horror! Thomas is 
human!!). JFFS2 had not shown this because it does not rely on oob to the 
same extent. This was discussed on the list sometime in May 2005. Some 
aspects of this were corrected, but it is not yet fully sound.

Since then, the AUTOPLACE thing has been somewhat of an open wound, awaiting 
resolution. During that time, pragmatic people have worked around the 
problem, however it has not been cured yet.

The good news though is that a fine fellow by the name of Vitaly Wool has 
started look at at some issues and clearly identifies the problem (see 
http://lists.infradead.org/pipermail/linux-mtd/2005-September/013949.html). I 
therefore hope for some resolution to this pretty soon. If Vitaly's 
suggestions come into being then the current code in YAFFS2 will work as it 
is with no modifications.

So that is pretty much a history of the AUTOPLACE business. Things don't 
always progress the way one hopes, and looking back I'd have done some things 
a bit differently.

As to these mtd interfaces being golden kernel interfaces: Not many people 
think so. Thomas doesn't. grep a whole Linux+yaffs source tree for read_oob 
and you'll only see references in mtd and yaffs. It is not like we're saying 
"change kalloc".

There is no immediate solution, but it looks like the proper solution should 
be there soon. I see Vitaly has proposed some patches. Thomas has asked me to 
look at them and comment. 

-- CHarles



[Technical side bar: Why the correct solution is to fix it in mtd]

There are many NAND types and implementations of hardware ECC etc, which means 
there are a lot of different ways to to bad block management and many 
different byte layouts on NAND.  For instance:
1) The default nand_base uses bytes 0 and 1 for bad block marking.
2) The HW_ECC for the S3C2410 uses these bytes for ECC.
3) Some, perhaps not designed yet, hardware might do something entirely 
different.

Further, one NAND driver might be serving up data to many file systems, so it 
is unreasonable to have a file system's preferred binary layout  This might 
even be impossible with some hardware anyway.

One of the fundamental tenets of Computer Science is to use abstract 
interfaces to hide detail. It is this thinking which lead to AUTOPLACE and 
the abstract bad block handling interface. This is nothing new and examples 
of abstract interfaces abound.

So the AUTOPLACE handling is there to provide a mechanism for abstracting away 
the physical location of oob bytes. It says "here are some bytes, save them 
whereever. When I ask for them back, then give them back. What every you do 
behind thescenes I don't want to know".

With an abstract interface, we can get around a lot of problems quite neatly:
1) Changes in mtd don't mean changes to YAFFS, or other file systems.
2) Implementation of some funky handware can be done without implementing new 
fields in oob_sel structures and having to fiddle multiple bodies of code. 
Optimal handling of data (for example special hardware tricks can be 
exploited).
3) Change in one place, test in one place, then it should "just work".

If we don't use an abstract interface then we get into a world of pain and we 
end up with code looking like 
http://www.aleph1.co.uk/pipermail/yaffs/2005q4/001581.html, which still does 
not handle all cases. This raises a bunch of problems including, but not 
limited to:
1) Replicated code. The algorithms are already in mtd so we should rather use 
them there.
2) mtd interaction. mtd changes. oobsel will most likely change again (it is 
now in about its third or fourth iteration). Don't want to have to change 
YAFFS and put in conditional code for even more changes.
2) Maintenance woes: We want to test YAFFS *once* and not have to test it 
against a zillion different hardware types etc and handle all the associated 
patches etc. When a problem is found, strict adherence to interfaces helps 
isolate problems.
3) If someone makes some new hardware/drivers that do not use oobsel, then we 
don't want to have to have to expose more detail to the outside world.
4) It is insane to use an abstract AUTOPLACE interface for some accesses, and 
not for others. It is important to use abstract interfaces consistently 
otherwise why have them at all?  {Analogy: When you write data to a serial 
port driver, you use some relatively abstract interface like write_byte(), 
you don't do something like outp(dev->uart->tx,b).]


-- Charles



More information about the yaffs mailing list