aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/early_res.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2010-02-10 04:20:27 -0500
committerH. Peter Anvin <hpa@zytor.com>2010-02-12 12:42:39 -0500
commit53db62a2529280ff216c941d8a2650204547e44a (patch)
treed36dba91fb6a1902aa5c2de70557ad858327ec75 /arch/x86/kernel/early_res.c
parentefdd0e81df0f23830c6d2cb971cf87f415b8dbdb (diff)
early_res: Enhance check_and_double_early_res
... to make it always try to start from low at first. This makes it less likely for early_memtest to reserve a bad range, in particular it puts new early_res in a range that is already tested. Signed-off-by: Yinghai Lu <yinghai@kernel.org> LKML-Reference: <1265793639-15071-24-git-send-email-yinghai@kernel.org> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/early_res.c')
-rw-r--r--arch/x86/kernel/early_res.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/arch/x86/kernel/early_res.c b/arch/x86/kernel/early_res.c
index 1b99a2619f9f..dbf08bd01252 100644
--- a/arch/x86/kernel/early_res.c
+++ b/arch/x86/kernel/early_res.c
@@ -180,9 +180,9 @@ void __init reserve_early_overlap_ok(u64 start, u64 end, char *name)
180 __reserve_early(start, end, name, 1); 180 __reserve_early(start, end, name, 1);
181} 181}
182 182
183static void __init __check_and_double_early_res(u64 start) 183static void __init __check_and_double_early_res(u64 ex_start, u64 ex_end)
184{ 184{
185 u64 end, size, mem; 185 u64 start, end, size, mem;
186 struct early_res *new; 186 struct early_res *new;
187 187
188 /* do we have enough slots left ? */ 188 /* do we have enough slots left ? */
@@ -190,10 +190,23 @@ static void __init __check_and_double_early_res(u64 start)
190 return; 190 return;
191 191
192 /* double it */ 192 /* double it */
193 end = max_pfn_mapped << PAGE_SHIFT; 193 mem = -1ULL;
194 size = sizeof(struct early_res) * max_early_res * 2; 194 size = sizeof(struct early_res) * max_early_res * 2;
195 mem = find_e820_area(start, end, size, sizeof(struct early_res)); 195 if (early_res == early_res_x)
196 196 start = 0;
197 else
198 start = early_res[0].end;
199 end = ex_start;
200 if (start + size < end)
201 mem = find_e820_area(start, end, size,
202 sizeof(struct early_res));
203 if (mem == -1ULL) {
204 start = ex_end;
205 end = max_pfn_mapped << PAGE_SHIFT;
206 if (start + size < end)
207 mem = find_e820_area(start, end, size,
208 sizeof(struct early_res));
209 }
197 if (mem == -1ULL) 210 if (mem == -1ULL)
198 panic("can not find more space for early_res array"); 211 panic("can not find more space for early_res array");
199 212
@@ -235,7 +248,7 @@ void __init reserve_early(u64 start, u64 end, char *name)
235 if (start >= end) 248 if (start >= end)
236 return; 249 return;
237 250
238 __check_and_double_early_res(end); 251 __check_and_double_early_res(start, end);
239 252
240 drop_overlaps_that_are_ok(start, end); 253 drop_overlaps_that_are_ok(start, end);
241 __reserve_early(start, end, name, 0); 254 __reserve_early(start, end, name, 0);
@@ -248,7 +261,7 @@ void __init reserve_early_without_check(u64 start, u64 end, char *name)
248 if (start >= end) 261 if (start >= end)
249 return; 262 return;
250 263
251 __check_and_double_early_res(end); 264 __check_and_double_early_res(start, end);
252 265
253 r = &early_res[early_res_count]; 266 r = &early_res[early_res_count];
254 267