diff mbox

[U-Boot,v2] ext2load: increase read speed

Message ID 1338566090-15008-1-git-send-email-u-boot@lakedaemon.net
State Accepted
Delegated to: Wolfgang Denk
Headers show

Commit Message

u-boot@lakedaemon.net June 1, 2012, 3:54 p.m. UTC
This patch dramatically drops the amount of time u-boot needs to read a
file from an ext2 partition.  On a typical 2 to 5 MB file (kernels and
initrds) it goes from tens of seconds to a couple seconds.

All we are doing here is grouping contiguous blocks into one read.

Boot tested on Globalscale Technologies Dreamplug (Kirkwood ARM SoC)
with three different files.  sha1sums were calculated in Linux
userspace, and then confirmed after ext2load.

The following test results were provided by Eric Nelson:

Tested on i.MX6 Sabre Lite board loading a file of ~900k:

Without patch:

      MX6QSABRELITE U-Boot > time ext2load sata 0:1 12000000
/usr/lib/libperl.so.5.12.4 && crc32 12000000 $filesize
      Loading file "/usr/lib/libperl.so.5.12.4" from sata device 0:1
      (hda1)
      958032 bytes read

      time: 0.414 seconds, 414 ticks
      CRC32 for 12000000 ... 120e9e4f ==> 550deec9

With patch:
      MX6QSABRELITE U-Boot > time ext2load sata 0:1 12000000
/usr/lib/libperl.so.5.12.4 && crc32 12000000 $filesize
      Loading file "/usr/lib/libperl.so.5.12.4" from sata device 0:1
      (hda1)
      958032 bytes read

      time: 0.205 seconds, 205 ticks
      CRC32 for 12000000 ... 120e9e4f ==> 550deec9

And, the following results were reported by Thierry Reding:

Before:

      Tegra2 (Medcom) # time ext2load mmc 0 0x17000000 /boot/uImage
      Loading file "/boot/uImage" from mmc device 0:1 (xxa1)
      5609104 bytes read

      time: 4.638 seconds, 4638 ticks
      Tegra2 (Medcom) # crc32 0x17000000 559690
      CRC32 for 17000000 ... 1755968f ==> 158788be

After:

      Tegra2 (Medcom) # time ext2load mmc 0 0x17000000 /boot/uImage
      Loading file "/boot/uImage" from mmc device 0:1 (xxa1)
      5609104 bytes read

      time: 0.317 seconds, 317 ticks
      Tegra2 (Medcom) # crc32 0x17000000 559690
      CRC32 for 17000000 ... 1755968f ==> 158788be

I can also successfully load the loaded uImage to a prompt

End results.

Signed-off-by: Jason Cooper <u-boot@lakedaemon.net>
Tested-by: Eric Nelson <eric.nelson@boundarydevices.com>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
---
Changes since v1:
  - updated commit entry to include test results from Eric Nelson and Thierry
    Reding

Based against tag 2012.04.01

 fs/ext2/ext2fs.c |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

Comments

Wolfgang Denk June 21, 2012, 8:49 p.m. UTC | #1
Dear Jason Cooper,

In message <1338566090-15008-1-git-send-email-u-boot@lakedaemon.net> you wrote:
> This patch dramatically drops the amount of time u-boot needs to read a
> file from an ext2 partition.  On a typical 2 to 5 MB file (kernels and
> initrds) it goes from tens of seconds to a couple seconds.
> 
> All we are doing here is grouping contiguous blocks into one read.
> 
> Boot tested on Globalscale Technologies Dreamplug (Kirkwood ARM SoC)
> with three different files.  sha1sums were calculated in Linux
> userspace, and then confirmed after ext2load.
> 
> The following test results were provided by Eric Nelson:
> 
> Tested on i.MX6 Sabre Lite board loading a file of ~900k:
> 
> Without patch:
> 
>       MX6QSABRELITE U-Boot > time ext2load sata 0:1 12000000
> /usr/lib/libperl.so.5.12.4 && crc32 12000000 $filesize
>       Loading file "/usr/lib/libperl.so.5.12.4" from sata device 0:1
>       (hda1)
>       958032 bytes read
> 
>       time: 0.414 seconds, 414 ticks
>       CRC32 for 12000000 ... 120e9e4f ==> 550deec9
> 
> With patch:
>       MX6QSABRELITE U-Boot > time ext2load sata 0:1 12000000
> /usr/lib/libperl.so.5.12.4 && crc32 12000000 $filesize
>       Loading file "/usr/lib/libperl.so.5.12.4" from sata device 0:1
>       (hda1)
>       958032 bytes read
> 
>       time: 0.205 seconds, 205 ticks
>       CRC32 for 12000000 ... 120e9e4f ==> 550deec9
> 
> And, the following results were reported by Thierry Reding:
> 
> Before:
> 
>       Tegra2 (Medcom) # time ext2load mmc 0 0x17000000 /boot/uImage
>       Loading file "/boot/uImage" from mmc device 0:1 (xxa1)
>       5609104 bytes read
> 
>       time: 4.638 seconds, 4638 ticks
>       Tegra2 (Medcom) # crc32 0x17000000 559690
>       CRC32 for 17000000 ... 1755968f ==> 158788be
> 
> After:
> 
>       Tegra2 (Medcom) # time ext2load mmc 0 0x17000000 /boot/uImage
>       Loading file "/boot/uImage" from mmc device 0:1 (xxa1)
>       5609104 bytes read
> 
>       time: 0.317 seconds, 317 ticks
>       Tegra2 (Medcom) # crc32 0x17000000 559690
>       CRC32 for 17000000 ... 1755968f ==> 158788be
> 
> I can also successfully load the loaded uImage to a prompt
> 
> End results.
> 
> Signed-off-by: Jason Cooper <u-boot@lakedaemon.net>
> Tested-by: Eric Nelson <eric.nelson@boundarydevices.com>
> Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
> ---
> Changes since v1:
>   - updated commit entry to include test results from Eric Nelson and Thierry
>     Reding
> 
> Based against tag 2012.04.01
> 
>  fs/ext2/ext2fs.c |   26 ++++++++++++++++++++++++--
>  1 files changed, 24 insertions(+), 2 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk
diff mbox

Patch

diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c
index f621741..f1fce48 100644
--- a/fs/ext2/ext2fs.c
+++ b/fs/ext2/ext2fs.c
@@ -420,7 +420,6 @@  int ext2fs_read_file
 		if (blknr < 0) {
 			return (-1);
 		}
-		blknr = blknr << log2blocksize;
 
 		/* Last block.  */
 		if (i == blockcnt - 1) {
@@ -438,6 +437,29 @@  int ext2fs_read_file
 			blockend -= skipfirst;
 		}
 
+		/* grab middle blocks in one go */
+		if (i != pos / blocksize && i != blockcnt - 1 && blockcnt > 3) {
+			int oldblk = blknr;
+			int blocknxt;
+			while (i < blockcnt - 1) {
+				blocknxt = ext2fs_read_block(node, i + 1);
+				if (blocknxt == (oldblk + 1)) {
+					oldblk = blocknxt;
+					i++;
+				} else {
+					blocknxt = ext2fs_read_block(node, i);
+					break;
+				}
+			}
+
+			if (oldblk == blknr)
+				blockend = blocksize;
+			else
+				blockend = (1 + blocknxt - blknr) * blocksize;
+		}
+
+		blknr = blknr << log2blocksize;
+
 		/* If the block number is 0 this block is not stored on disk but
 		   is zero filled instead.  */
 		if (blknr) {
@@ -450,7 +472,7 @@  int ext2fs_read_file
 		} else {
 			memset (buf, 0, blocksize - skipfirst);
 		}
-		buf += blocksize - skipfirst;
+		buf += blockend - skipfirst;
 	}
 	return (len);
 }