[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <tip-2d2da60fb40a80cc59383121ccf763e0e0e8a42a@git.kernel.org>
Date: Fri, 16 Dec 2011 10:43:02 -0800
From: tip-bot for Maarten Lankhorst <m.b.lankhorst@...il.com>
To: linux-tip-commits@...r.kernel.org
Cc: linux-kernel@...r.kernel.org, hpa@...or.com, mingo@...hat.com,
m.b.lankhorst@...il.com, tglx@...utronix.de, hpa@...ux.intel.com
Subject: [tip:x86/efi] x86, efi: Break up large initrd reads
Commit-ID: 2d2da60fb40a80cc59383121ccf763e0e0e8a42a
Gitweb: http://git.kernel.org/tip/2d2da60fb40a80cc59383121ccf763e0e0e8a42a
Author: Maarten Lankhorst <m.b.lankhorst@...il.com>
AuthorDate: Fri, 16 Dec 2011 13:30:58 +0100
Committer: H. Peter Anvin <hpa@...ux.intel.com>
CommitDate: Fri, 16 Dec 2011 08:34:35 -0800
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 4MiB, so use a
safe value.
elilo reads in chunks of 16KiB, but since that requires many read
calls I use a value of 1 MiB. hpa suggested adding individual
blacklists for when systems are found where this value causes a crash.
Signed-off-by: Maarten Lankhorst <m.b.lankhorst@...il.com>
Link: http://lkml.kernel.org/r/4EEB3A02.3090201@gmail.com
Signed-off-by: H. Peter Anvin <hpa@...ux.intel.com>
---
arch/x86/boot/compressed/eboot.c | 20 ++++++++++++++------
arch/x86/boot/compressed/eboot.h | 1 +
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 4055e63..fec216f 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -643,14 +643,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 > EFI_READ_CHUNK_SIZE)
+ chunksize = EFI_READ_CHUNK_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;
}
}
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
index f66d023..3925166 100644
--- a/arch/x86/boot/compressed/eboot.h
+++ b/arch/x86/boot/compressed/eboot.h
@@ -12,6 +12,7 @@
#define DESC_TYPE_CODE_DATA (1 << 0)
#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
+#define EFI_READ_CHUNK_SIZE (1024 * 1024)
#define PIXEL_RGB_RESERVED_8BIT_PER_COLOR 0
#define PIXEL_BGR_RESERVED_8BIT_PER_COLOR 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