Re: [Yaffs] Proposals for speeding up shutdown

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Charles Manning
Date:  
To: Hugo Etchegoyen
CC: yaffs
New-Topics: [Yaffs] GC logic, Re: [Yaffs] background GC
Subject: Re: [Yaffs] Proposals for speeding up shutdown
On Thursday 18 March 2010 04:50:56 Hugo Etchegoyen wrote:
> Charles,
>
> As I said in a previous mail, I was looking for means of speeding up
> yaffs shutdown during power fail, and that included disabling GC. Your
> last modification (the yaffs_gc_control parameter) addresses that issue.
>
> However, although setting this flag to zero will prevent entering GC, it
> will not abort a currently active GC. I had originally proposed to
> decrease the value of maxCopies in GarbageCollectBlock() to make it
> finer grained, but it looks faster and safer to just check your flag in
> each iteration of the copying loop:
>
>         for (/* init already done */;
>              retVal == YAFFS_OK &&
>              dev->gcChunk < dev->param.nChunksPerBlock &&
>              (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) &&
>              maxCopies > 0;
>              dev->gcChunk++, oldChunk++) {

>
>             if(dev->param.gcControl &&
>                 (dev->param.gcControl(dev) & 1) == 0)
>                     break;

>
>             if (yaffs_CheckChunkBit(dev, block, dev->gcChunk)) {

>
>                 /* This page is in use and might need to be copied off */
>              ...


Doing that should be fine. It should be OK to interrupt gc at any page. That's
pretty much what the maxCopy stuff is doing anyway.

I would tend to push the gcControl check into the for().




>
> As yaffs may now be shut down disabling GC, and depending on how much
> data is written with GC disabled (less than a block size in my case),
> maybe at initialization time there might be less free blocks than
> advisable. So I thought that it might be useful to catch up with delayed
> GCs at the end of yaffs_GutsInitialise(). Do you think this is
> necessary/advisable?


I don't think it is necessary.

> Would this code handle that correctly?
>
>     /* Clean up any aborted checkpoint data */
>     if(!dev->isCheckpointed && dev->blocksInCheckpoint > 0)
>         yaffs_InvalidateCheckpoint(dev);

>



>     /* Honor any pending GCs */
>     do {
>         x = dev->nErasedBlocks;
>         yaffs_CheckGarbageCollection(dev);
>     } while ( dev->gcBlock > 0 || x < dev->nErasedBlocks );

>


There is no need to resume any gc per se. yaffs_CheckGarbageCollection()
already does iteration.

If you do it here then the checkpoint will be immediately invalidated which is
perhaps not a good idea. You might as well just leave this to be sorted out
on the first write.


>     T(YAFFS_TRACE_TRACING,
>       (TSTR("yaffs: yaffs_GutsInitialise() done.\n" TENDSTR)));

>
>     return YAFFS_OK;

>
> I also noticed that there is a possible source of delay when updating
> dirty directories, since once started it will iterate over a list of
> pending updates with the yaffs lock taken. I propose adding another
> flag, yaffs_udd_control ("udd" for Update Dirty Directories) and the
> corresponding callback (dev->uddControl). Then
> yaffs_UpdateDirtyDirectories() can check this flag in each iteration of
> the updating loop:
>
>     while(!ylist_empty(&dev->dirtyDirectories)){

>
>         if(dev->param.uddControl &&
>             (dev->param.uddControl(dev) & 1) == 0)
>             break;

>
>         link = dev->dirtyDirectories.next;
>         ylist_del_init(link);
>         ...


That should be fine to do,
I'll be adding flags like these when I flesh out the background task with
background garbage collection etc.

> Please advise if these modifications are OK. I have attached the
> modified files (yaffs_guts.h, yaffs_guts.c and yaffs_fs.c). I have
> compiled and tried the module and it seems to work properly, including
> disabling GC and UDD, writing some data, then enabling them again and
> writing some more. I haven't yet simulated a power fail situation when
> one would abort an ongoing GC or UDD, then write some data, sync and
> unmount. I'll report back as soon as I can try that.
>
> Best regards,
> Hugo