From: Bjorn Helgaas <bjorn.helgaas@hp.com>
To: linux-ia64@vger.kernel.org
Subject: [PATCH] fix EFI memory map trimming
Date: Fri, 17 Oct 2003 22:13:44 +0000 [thread overview]
Message-ID: <marc-linux-ia64-106642910714855@msgid-missing> (raw)
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)
next reply other threads:[~2003-10-17 22:13 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-17 22:13 Bjorn Helgaas [this message]
2003-10-18 1:09 ` [PATCH] fix EFI memory map trimming David Mosberger
2003-10-20 15:54 ` Bjorn Helgaas
2003-10-20 18:55 ` David Mosberger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=marc-linux-ia64-106642910714855@msgid-missing \
--to=bjorn.helgaas@hp.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.