From: Jack Steiner <steiner@sgi.com>
To: lenb@kernel.org
Cc: hpa@zytor.com, hmh@hmh.eng.br, tony.luck@gmail.com,
linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
gbeshers@sgi.com
Subject: [PATCH] - Mapping ACPI tables as CACHED
Date: Tue, 14 Dec 2010 16:09:32 -0600 [thread overview]
Message-ID: <20101214220932.GA1206@sgi.com> (raw)
Map ACPI tables as WB on x86_64. No substantive changes to IA64.
Large SGI UV systems (3072p, 5TB) take a long time to boot. A significant
part of the boot time is scanning ACPI tables. ACPI tables on UV systems
are located in RAM memory that is physically attached to node 0.
User programs (ex., acpidump) read the ACPI tables by mapping them thru
/dev/mem. Although mmap tries to map the tables as CACHED, there are
existing kernel UNCACHED mapping that conflict and the tables end up as
being mapped UNCACHED. (See the call to track_pfn_vma_new() in
remap_pfn_range()).
Much of the access is to small fields (bytes (checksums), shorts, etc).
Late in boot, there is significant scanning of the ACPI tables that take
place from nodes other than zero. Since the tables are not cached, each
reference accesses physical memory that is attached to remote nodes. These
memory requests must cross the numalink interconnect which adds several
hundred nsec to each access. This slows the boot process. Access from
node 0, although faster, is still very slow.
The following patch changes the kernel mapping for ACPI tables
to CACHED. This eliminates the page attibute conflict & allows users to map
the tables CACHEABLE. This significantly speeds up boot:
38 minutes without the patch
27 minutes with the patch
~30% improvement
Time to run ACPIDUMP on a large system:
527 seconds without the patch
8 seconds with the patch
Signed-off-by: Jack Steiner <steiner@sgi.com>
---
(resend of earlier patch)
http://marc.info/?l=linux-kernel&m=128206079905826&w=2
http://marc.info/?l=linux-acpi&m=128284304032481&w=2
V2 - Change the patch to unconditionally map ACPI tables as WB on x86_64.
V3 - same as V2 except updated to 2.6.37-rc5
---
arch/ia64/kernel/acpi.c | 6 ++++++
arch/x86/kernel/acpi/boot.c | 14 ++++++++++++++
drivers/acpi/osl.c | 2 +-
include/linux/acpi.h | 1 +
4 files changed, 22 insertions(+), 1 deletion(-)
Index: linux/arch/ia64/kernel/acpi.c
===================================================================
--- linux.orig/arch/ia64/kernel/acpi.c 2010-12-14 15:51:33.230235579 -0600
+++ linux/arch/ia64/kernel/acpi.c 2010-12-14 16:02:26.718529904 -0600
@@ -176,6 +176,12 @@ void __init __acpi_unmap_table(char *map
{
}
+char *__init __acpi_map_table_permanent(unsigned long phys_addr,
+ unsigned long size)
+{
+ return ioremap(phys_addr, size);
+}
+
/* --------------------------------------------------------------------------
Boot-time Table Parsing
-------------------------------------------------------------------------- */
Index: linux/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux.orig/arch/x86/kernel/acpi/boot.c 2010-12-14 15:51:33.230235579 -0600
+++ linux/arch/x86/kernel/acpi/boot.c 2010-12-14 15:52:06.070227289 -0600
@@ -167,6 +167,20 @@ void __init __acpi_unmap_table(char *map
early_iounmap(map, size);
}
+/*
+ * Permanently map memory for ACPI. Map ACPI tables and RAM as WB,
+ * other regions as UC.
+ */
+char *__init __acpi_map_table_permanent(unsigned long phys, unsigned long size)
+{
+ if (e820_all_mapped(phys, phys + size, E820_RAM) ||
+ e820_all_mapped(phys, phys + size, E820_ACPI) ||
+ e820_all_mapped(phys, phys + size, E820_NVS))
+ return ioremap_cache((unsigned long)phys, size);
+ else
+ return ioremap(phys, size);
+}
+
#ifdef CONFIG_X86_LOCAL_APIC
static int __init acpi_parse_madt(struct acpi_table_header *table)
{
Index: linux/drivers/acpi/osl.c
===================================================================
--- linux.orig/drivers/acpi/osl.c 2010-12-14 15:51:33.230235579 -0600
+++ linux/drivers/acpi/osl.c 2010-12-14 15:52:06.098240079 -0600
@@ -324,7 +324,7 @@ acpi_os_map_memory(acpi_physical_address
pg_off = round_down(phys, PAGE_SIZE);
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
- virt = ioremap(pg_off, pg_sz);
+ virt = __acpi_map_table_permanent(pg_off, pg_sz);
if (!virt) {
kfree(map);
return NULL;
Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h 2010-12-14 15:51:33.230235579 -0600
+++ linux/include/linux/acpi.h 2010-12-14 16:03:23.042529564 -0600
@@ -77,6 +77,7 @@ typedef int (*acpi_table_handler) (struc
typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
+char *__acpi_map_table_permanent(unsigned long phys_addr, unsigned long size);
void __acpi_unmap_table(char *map, unsigned long size);
int early_acpi_boot_init(void);
int acpi_boot_init (void);
next reply other threads:[~2010-12-14 22:09 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-14 22:09 Jack Steiner [this message]
2010-12-14 22:58 ` [PATCH] - Mapping ACPI tables as CACHED H. Peter Anvin
2010-12-14 23:22 ` Len Brown
2010-12-15 0:26 ` H. Peter Anvin
2010-12-15 2:27 ` Jack Steiner
2010-12-15 4:17 ` H. Peter Anvin
2010-12-15 0:04 ` Len Brown
2010-12-15 1:18 ` H. Peter Anvin
2010-12-15 2:40 ` Len Brown
2010-12-15 2:41 ` Jack Steiner
2010-12-15 4:03 ` Len Brown
2010-12-15 4:35 ` Len Brown
2010-12-15 6:17 ` H. Peter Anvin
2010-12-15 6:17 ` Milton Miller
2010-12-15 6:29 ` H. Peter Anvin
2010-12-15 16:46 ` Jack Steiner
2010-12-15 21:16 ` Len Brown
2010-12-15 22:18 ` H. Peter Anvin
2010-12-17 2:54 ` Len Brown
2010-12-17 8:08 ` [PATCH] ACPI: use ioremap_cache() Len Brown
2010-12-27 19:42 ` Tony Luck
2010-12-27 20:12 ` H. Peter Anvin
2010-12-28 3:21 ` Shaohua Li
2010-12-28 3:35 ` H. Peter Anvin
2010-12-28 5:02 ` Shaohua Li
2010-12-28 20:12 ` H. Peter Anvin
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=20101214220932.GA1206@sgi.com \
--to=steiner@sgi.com \
--cc=gbeshers@sgi.com \
--cc=hmh@hmh.eng.br \
--cc=hpa@zytor.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tony.luck@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox