[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4ECEF144.8020303@gmail.com>
Date: Fri, 25 Nov 2011 02:37:08 +0100
From: Maarten Lankhorst <m.b.lankhorst@...il.com>
To: Matt Fleming <matt@...sole-pimps.org>
CC: "H. Peter Anvin" <hpa@...ux.intel.com>,
Matthew Garrett <mjg@...hat.com>, linux-kernel@...r.kernel.org,
Ingo Molnar <mingo@...e.hu>,
Thomas Gleixner <tglx@...utronix.de>, x86@...nel.org,
Mike Waychison <mikew@...gle.com>,
Andi Kleen <andi@...stfloor.org>,
Peter Jones <pjones@...hat.com>
Subject: [PATCH] x86, efi: Break up large initrd reads
The efi boot stub tries to read the entire initrd in 1 go,
however some efi implementations hang if too much if asked
to read too much data at the same time. After some
experimentation I found out that my asrock p67 board will
hang if asked to read chunks of 4mb, so use a safe value.
>From elilo source code:
/*
* We load by chunks rather than a single big read because
* early versions of EFI had troubles loading files
* from floppies in a single big request. Breaking
* the read down into chunks of 4KB fixed that
* problem. While this problem has been fixed, we still prefer
* this method because it tells us whether or not we're making
* forward progress.
*/
While the comment says 4KB, it's using 4 * EFI_PAGE_SIZE (16KB),
so I went by the safest route of following elilo here.
Signed-off-by: Maarten Lankhorst <m.b.lankhorst@...il.com>
---
arch/x86/boot/compressed/eboot.c | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 8627a56..a26be50 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -695,14 +695,22 @@ grow:
u64 size;
size = initrds[j].size;
- status = efi_call_phys3(fh->read, initrds[j].handle,
- &size, addr);
- if (status != EFI_SUCCESS)
- goto free_initrd_total;
+ while (size) {
+ u64 chunksize;
+ if (size > 4 * EFI_PAGE_SIZE)
+ chunksize = 4 * EFI_PAGE_SIZE;
+ else
+ chunksize = size;
+ status = efi_call_phys3(fh->read,
+ initrds[j].handle,
+ &chunksize, addr);
+ if (status != EFI_SUCCESS)
+ goto free_initrd_total;
+ addr += chunksize;
+ size -= chunksize;
+ }
efi_call_phys1(fh->close, initrds[j].handle);
-
- addr += size;
}
}
--
1.7.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists