Proposed logic for fs-update zeroed blocks optimization

Daniel Drake dsd at laptop.org
Tue Apr 19 13:09:09 EDT 2011


Maybe dependent on the possibility of an extX-specific optimization in
the .zd file, this may or may not be relevant, or may be worth doing
anyway (on a generic basis):

The .zd files currently contain loads of zero blocks, fs-update erases
the SD card at the start, most SD cards erase to zeroes. So we can
skip writing lots of blocks, resulting in much shorter fs-update time.

Proposed logic:

In the erase method of the disk node, if this is the first time during
this session that we are erasing blocks on this card, we read back the
first block that was erased to see if it erased to all-zero or
all-ones, and we store this result in memory.

A "erase-byte" method is added to the disk node, which returns 0x00 if
the disk erases to zero, and 0xff if the disk erases to ones.
To determine this result, we look at what happened when we erased the
blocks. If this method is called without us having erased some blocks
in advance, we instead read the card SCR and examine bit 55 and return
the value based on that.
It is documented that erase-byte is most reliable only when called
after erasing some part of the disk.

In the fs-update codepath, after erasing the blocks, we call
erase-byte and store the result locally. When writing each zblock, we
look for either of the following conditions, allowing us to skip
writing that block:
 1. Block is all-ones and disk erases to ones
 2. Block is all-zeroes and disk erases to zeroes

I've attached a patch which illustrates how to detect and skip all-zero blocks.

Daniel
-------------- next part --------------
Index: cpu/x86/pc/olpc/via/fsupdate.fth
===================================================================
--- cpu/x86/pc/olpc/via/fsupdate.fth	(revisiĆ³n: 2188)
+++ cpu/x86/pc/olpc/via/fsupdate.fth	(copia de trabajo)
@@ -9,6 +9,7 @@
 ;
 
 0 value #eblocks-written
+0 value #eblocks-skipped
 
 : ?all-written  ( -- )
    #eblocks-written #image-eblocks <>  if
@@ -174,15 +175,17 @@
    get-hex#                              ( eblock# )
    get-hex# >r                           ( eblock# r: comprlen )
    safe-parse-word                       ( eblock# hashname$ r: comprlen )
-   safe-parse-word hex-decode            ( eblock# hashname$ [ hash$ ] err? r: comprlen )
+   safe-parse-word 2dup hex-decode            ( eblock# hashname$ hash$ [ hash$ ] err? r: comprlen )
    " Malformed hash string" ?nand-abort  ( eblock# hashname$ hash$ r: comprlen )
 
    ?get-crc                              ( eblock# hashname$ hash$ r: comprlen )
 
-\  2dup  " fa43239bcee7b97ca62f007cc68487560a39e19f74f3dde7486db3f98df8e471" $=  if  ( eblock# hashname$ hash$ r: comprlen)
-\     r> skip-zdata                         ( eblock# hashname$ hash$ )
-\     2drop 2drop                           ( eblock# )
-\  else                                     ( eblock# hashname$ hash$ )
+   2swap " fa43239bcee7b97ca62f007cc68487560a39e19f74f3dde7486db3f98df8e471"
+   $=  if  ( eblock# hashname$ hash$ r: comprlen)
+     r> skip-zdata                         ( eblock# hashname$ hash$ )
+     2drop 2drop                           ( eblock# )
+     #eblocks-skipped 1+ to #eblocks-skipped
+   else                                     ( eblock# hashname$ hash$ )
       r> get-zdata                          ( eblock# hashname$ hash$ )
       ?check-crc                            ( eblock# hashname$ hash$ )
 
@@ -198,11 +201,12 @@
 \   data-buffer over nand-pages/block *  nand-pages/block  " write-blocks" $call-nand  ( eblock# #written )
 \   nand-pages/block  <>  " Write error" ?nand-abort   ( eblock# )
       swap-buffers                          ( eblock# )
-\  then
+   then
 
    show-written                             ( )
    #eblocks-written 1+ to #eblocks-written  ( )
    show-temperature
+   space #eblocks-skipped .d
    hdd-led-toggle
 ;
 


More information about the Devel mailing list