* [PATCH] fix EFI memory map trimming
@ 2003-10-17 22:13 Bjorn Helgaas
2003-10-18 1:09 ` David Mosberger
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Bjorn Helgaas @ 2003-10-17 22:13 UTC (permalink / raw)
To: linux-ia64
This fixes a problem in EFI memory map trimming. I've never been
able to wrap my head around the existing code, so this is perhaps
more of a rewrite than it ought to be, but ... well, you can see
what you think.
For example, here's part of the memory map on my i2000:
mem00: type=4, attr=0x9, range=[0x0000000000000000-0x0000000000001000) (0MB)
mem01: type=7, attr=0x9, range=[0x0000000000001000-0x0000000000088000) (0MB)
mem02: type=4, attr=0x9, range=[0x0000000000088000-0x00000000000a0000) (0MB)
mem03: type=5, attr=0x8000000000000009, range=[0x00000000000c0000-0x0000000000100000) (0MB)
mem04: type=7, attr=0x9, range=[0x0000000000100000-0x0000000004000000) (63MB)
mem05: type=2, attr=0x9, range=[0x0000000004000000-0x00000000049ba000) (9MB)
mem06: type=7, attr=0x9, range=[0x00000000049ba000-0x000000007ec0b000) (1954MB)
...
There's a hole at 0xa0000-0xc0000, so we should ignore all the WB memory
in that granule. With 16MB granules, the existing code trims like this
(note the 4K page at 0x0 should have been ignored, but wasn't):
efi.trim_bottom: ignoring 540KB of memory at 0x1000 due to granule hole at 0x0
efi.trim_bottom: ignoring 96KB of memory at 0x88000 due to granule hole at 0x0
efi.trim_bottom: ignoring 15360KB of memory at 0x100000 due to granule hole at 0x0
The patch makes it trim correctly, like this:
efi.trim_top: ignoring 4KB of memory at 0x0 due to granule hole at 0x0
efi.trim_top: ignoring 540KB of memory at 0x1000 due to granule hole at 0x0
efi.trim_top: ignoring 96KB of memory at 0x88000 due to granule hole at 0x0
efi.trim_bottom: ignoring 15360KB of memory at 0x100000 due to granule hole at 0x0
This patch is for 2.6.
Bjorn
=== arch/ia64/kernel/efi.c 1.24 vs edited ==--- 1.24/arch/ia64/kernel/efi.c Wed Sep 10 08:26:40 2003
+++ edited/arch/ia64/kernel/efi.c Fri Oct 17 12:51:59 2003
@@ -297,9 +297,9 @@
u64 start;
u64 end;
} prev, curr;
- void *efi_map_start, *efi_map_end, *p, *q, *r;
+ void *efi_map_start, *efi_map_end, *p, *q;
efi_memory_desc_t *md, *check_md;
- u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0;
+ u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0;
efi_map_start = __va(ia64_boot_param->efi_memmap);
efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
@@ -312,41 +312,34 @@
if (!(md->attribute & EFI_MEMORY_WB))
continue;
- if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) {
- /*
- * Search for the next run of contiguous WB memory. Start search
- * at first granule boundary covered by md.
- */
- granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1)
- & -IA64_GRANULE_SIZE);
- first_non_wb_addr = granule_addr;
- for (q = p; q < efi_map_end; q += efi_desc_size) {
- check_md = q;
-
- if (check_md->attribute & EFI_MEMORY_WB)
- trim_bottom(check_md, granule_addr);
-
- if (check_md->phys_addr < granule_addr)
- continue;
+ /*
+ * granule_addr is the base of md's first granule.
+ * [granule_addr - first_non_wb_addr) is guaranteed to
+ * be contiguous WB memory.
+ */
+ granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
+ first_non_wb_addr = max(first_non_wb_addr, granule_addr);
- if (!(check_md->attribute & EFI_MEMORY_WB))
- break; /* hit a non-WB region; stop search */
+ if (first_non_wb_addr < md->phys_addr) {
+ trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
+ granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
+ first_non_wb_addr = max(first_non_wb_addr, granule_addr);
+ }
- if (check_md->phys_addr != first_non_wb_addr)
- break; /* hit a memory hole; stop search */
+ for (q = p; q < efi_map_end; q += efi_desc_size) {
+ check_md = q;
+ if (check_md->attribute & EFI_MEMORY_WB &&
+ check_md->phys_addr = first_non_wb_addr)
first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
- }
- /* round it down to the previous granule-boundary: */
- first_non_wb_addr &= -IA64_GRANULE_SIZE;
-
- if (!(first_non_wb_addr > granule_addr))
- continue; /* couldn't find enough contiguous memory */
-
- for (r = p; r < q; r += efi_desc_size)
- trim_top(r, first_non_wb_addr);
+ else
+ break; /* non-WB or hole */
}
+ last_granule_addr = first_non_wb_addr & ~(IA64_GRANULE_SIZE - 1);
+ if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
+ trim_top(md, last_granule_addr);
+
if (is_available_memory(md)) {
if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
if (md->phys_addr > mem_limit)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] fix EFI memory map trimming
2003-10-17 22:13 [PATCH] fix EFI memory map trimming Bjorn Helgaas
@ 2003-10-18 1:09 ` David Mosberger
2003-10-20 15:54 ` Bjorn Helgaas
2003-10-20 18:55 ` David Mosberger
2 siblings, 0 replies; 4+ messages in thread
From: David Mosberger @ 2003-10-18 1:09 UTC (permalink / raw)
To: linux-ia64
>>>>> On Fri, 17 Oct 2003 16:13:44 -0600, Bjorn Helgaas <bjorn.helgaas@hp.com> said:
Bjorn> This fixes a problem in EFI memory map trimming. I've never
Bjorn> been able to wrap my head around the existing code, so this
Bjorn> is perhaps more of a rewrite than it ought to be, but
Bjorn> ... well, you can see what you think.
I think it's a nice improvement and not too much of a rewrite. Just
one small suggestion:
+ if (check_md->attribute & EFI_MEMORY_WB &&
+ check_md->phys_addr = first_non_wb_addr)
This needs a pair of parens to avoid a compiler warning, I think.
--david
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] fix EFI memory map trimming
2003-10-17 22:13 [PATCH] fix EFI memory map trimming Bjorn Helgaas
2003-10-18 1:09 ` David Mosberger
@ 2003-10-20 15:54 ` Bjorn Helgaas
2003-10-20 18:55 ` David Mosberger
2 siblings, 0 replies; 4+ messages in thread
From: Bjorn Helgaas @ 2003-10-20 15:54 UTC (permalink / raw)
To: linux-ia64
On Friday 17 October 2003 7:09 pm, David Mosberger wrote:
> + if (check_md->attribute & EFI_MEMORY_WB &&
> + check_md->phys_addr = first_non_wb_addr)
>
> This needs a pair of parens to avoid a compiler warning, I think.
gcc-3.3.2 doesn't warn either way, but here's a version with
the extra parens:
=== arch/ia64/kernel/efi.c 1.24 vs edited ==--- 1.24/arch/ia64/kernel/efi.c Wed Sep 10 08:26:40 2003
+++ edited/arch/ia64/kernel/efi.c Mon Oct 20 09:51:02 2003
@@ -297,9 +297,9 @@
u64 start;
u64 end;
} prev, curr;
- void *efi_map_start, *efi_map_end, *p, *q, *r;
+ void *efi_map_start, *efi_map_end, *p, *q;
efi_memory_desc_t *md, *check_md;
- u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0;
+ u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0;
efi_map_start = __va(ia64_boot_param->efi_memmap);
efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
@@ -312,41 +312,34 @@
if (!(md->attribute & EFI_MEMORY_WB))
continue;
- if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) {
- /*
- * Search for the next run of contiguous WB memory. Start search
- * at first granule boundary covered by md.
- */
- granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1)
- & -IA64_GRANULE_SIZE);
- first_non_wb_addr = granule_addr;
- for (q = p; q < efi_map_end; q += efi_desc_size) {
- check_md = q;
-
- if (check_md->attribute & EFI_MEMORY_WB)
- trim_bottom(check_md, granule_addr);
-
- if (check_md->phys_addr < granule_addr)
- continue;
+ /*
+ * granule_addr is the base of md's first granule.
+ * [granule_addr - first_non_wb_addr) is guaranteed to
+ * be contiguous WB memory.
+ */
+ granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
+ first_non_wb_addr = max(first_non_wb_addr, granule_addr);
- if (!(check_md->attribute & EFI_MEMORY_WB))
- break; /* hit a non-WB region; stop search */
+ if (first_non_wb_addr < md->phys_addr) {
+ trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
+ granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
+ first_non_wb_addr = max(first_non_wb_addr, granule_addr);
+ }
- if (check_md->phys_addr != first_non_wb_addr)
- break; /* hit a memory hole; stop search */
+ for (q = p; q < efi_map_end; q += efi_desc_size) {
+ check_md = q;
+ if ((check_md->attribute & EFI_MEMORY_WB) &&
+ (check_md->phys_addr = first_non_wb_addr))
first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
- }
- /* round it down to the previous granule-boundary: */
- first_non_wb_addr &= -IA64_GRANULE_SIZE;
-
- if (!(first_non_wb_addr > granule_addr))
- continue; /* couldn't find enough contiguous memory */
-
- for (r = p; r < q; r += efi_desc_size)
- trim_top(r, first_non_wb_addr);
+ else
+ break; /* non-WB or hole */
}
+ last_granule_addr = first_non_wb_addr & ~(IA64_GRANULE_SIZE - 1);
+ if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
+ trim_top(md, last_granule_addr);
+
if (is_available_memory(md)) {
if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
if (md->phys_addr > mem_limit)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] fix EFI memory map trimming
2003-10-17 22:13 [PATCH] fix EFI memory map trimming Bjorn Helgaas
2003-10-18 1:09 ` David Mosberger
2003-10-20 15:54 ` Bjorn Helgaas
@ 2003-10-20 18:55 ` David Mosberger
2 siblings, 0 replies; 4+ messages in thread
From: David Mosberger @ 2003-10-20 18:55 UTC (permalink / raw)
To: linux-ia64
>>>>> On Mon, 20 Oct 2003 09:54:16 -0600, Bjorn Helgaas <bjorn.helgaas@hp.com> said:
Bjorn> On Friday 17 October 2003 7:09 pm, David Mosberger wrote:
>> + if (check_md->attribute & EFI_MEMORY_WB &&
>> + check_md->phys_addr = first_non_wb_addr)
>> This needs a pair of parens to avoid a compiler warning, I think.
Bjorn> gcc-3.3.2 doesn't warn either way, but here's a version with
Bjorn> the extra parens:
Huh, you're right (neither does gcc-2.96, for example). My mistake.
Still, I think the code is clearer with parens.
I applied the patch now, thanks.
--david
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-10-20 18:55 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-17 22:13 [PATCH] fix EFI memory map trimming Bjorn Helgaas
2003-10-18 1:09 ` David Mosberger
2003-10-20 15:54 ` Bjorn Helgaas
2003-10-20 18:55 ` David Mosberger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox