From: Jeremy Fitzhardinge <jeremy@goop.org>
To: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Yasunori Goto <y-goto@jp.fujitsu.com>,
Dave Hansen <dave@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>, LKML <linux-kernel@vger.kernel.org>,
Christoph Lameter <clameter@sgi.com>
Subject: [PATCH 2 of 6] xen: make phys_to_machine structure dynamic
Date: Thu, 03 Apr 2008 17:05:42 -0700 [thread overview]
Message-ID: <ba2c061db66983f9415c.1207267542@localhost> (raw)
In-Reply-To: <patchbomb.1207267540@localhost>
We now support the use of memory hotplug, so the physical to machine
page mapping structure must be dynamic. This is implemented as a
two-level radix tree structure, which allows us to efficiently
incrementally allocate memory for the p2m table as new pages are
added.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
---
arch/x86/xen/enlighten.c | 2 -
arch/x86/xen/mmu.c | 85 ++++++++++++++++++++++++++++++++++++++++++++
arch/x86/xen/setup.c | 2 -
arch/x86/xen/xen-ops.h | 2 +
include/asm-x86/xen/page.h | 20 +++-------
5 files changed, 94 insertions(+), 17 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1207,7 +1207,7 @@
/* Get mfn list */
if (!xen_feature(XENFEAT_auto_translated_physmap))
- phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list;
+ xen_build_dynamic_phys_to_machine();
pgd = (pgd_t *)xen_start_info->pt_base;
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -55,6 +55,91 @@
#include "multicalls.h"
#include "mmu.h"
+
+/*
+ * This should probably be a config option. On 32-bit, it costs 1
+ * page/gig of memory; on 64-bit its 2 pages/gig. If we want it to be
+ * completely unbounded we can add another level to the p2m structure.
+ */
+#define MAX_GUEST_PAGES (16ull * 1024*1024*1024 / PAGE_SIZE)
+#define P2M_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
+
+static unsigned long *p2m_top[MAX_GUEST_PAGES / P2M_ENTRIES_PER_PAGE];
+
+static inline unsigned p2m_top_index(unsigned long pfn)
+{
+ BUG_ON(pfn >= MAX_GUEST_PAGES);
+ return pfn / P2M_ENTRIES_PER_PAGE;
+}
+
+static inline unsigned p2m_index(unsigned long pfn)
+{
+ return pfn % P2M_ENTRIES_PER_PAGE;
+}
+
+void __init xen_build_dynamic_phys_to_machine(void)
+{
+ unsigned pfn;
+ unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list;
+
+ BUG_ON(xen_start_info->nr_pages >= MAX_GUEST_PAGES);
+
+ for(pfn = 0;
+ pfn < xen_start_info->nr_pages;
+ pfn += P2M_ENTRIES_PER_PAGE) {
+ unsigned topidx = p2m_top_index(pfn);
+
+ p2m_top[topidx] = &mfn_list[pfn];
+ }
+}
+
+unsigned long get_phys_to_machine(unsigned long pfn)
+{
+ unsigned topidx, idx;
+
+ topidx = p2m_top_index(pfn);
+ if (p2m_top[topidx] == NULL)
+ return INVALID_P2M_ENTRY;
+
+ idx = p2m_index(pfn);
+ return p2m_top[topidx][idx];
+}
+
+static void alloc_p2m(unsigned long **pp)
+{
+ unsigned long *p;
+ unsigned i;
+
+ p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
+ BUG_ON(p == NULL);
+
+ for(i = 0; i < P2M_ENTRIES_PER_PAGE; i++)
+ p[i] = INVALID_P2M_ENTRY;
+
+ if (cmpxchg(pp, NULL, p) != NULL)
+ free_page((unsigned long)p);
+}
+
+void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+ unsigned topidx, idx;
+
+ if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) {
+ BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+ return;
+ }
+
+ topidx = p2m_top_index(pfn);
+ if (p2m_top[topidx] == NULL) {
+ /* no need to allocate a page to store an invalid entry */
+ if (mfn == INVALID_P2M_ENTRY)
+ return;
+ alloc_p2m(&p2m_top[topidx]);
+ }
+
+ idx = p2m_index(pfn);
+ p2m_top[topidx][idx] = mfn;
+}
xmaddr_t arbitrary_virt_to_machine(unsigned long address)
{
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -27,8 +27,6 @@
extern const char xen_hypervisor_callback[];
extern const char xen_failsafe_callback[];
-unsigned long *phys_to_machine_mapping;
-EXPORT_SYMBOL(phys_to_machine_mapping);
/**
* machine_specific_memory_setup - Hook for machine specific memory setup.
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -21,6 +21,8 @@
void __init xen_arch_setup(void);
void __init xen_init_IRQ(void);
void xen_enable_sysenter(void);
+
+void __init xen_build_dynamic_phys_to_machine(void);
void xen_setup_timer(int cpu);
void xen_setup_cpu_clockevents(void);
diff --git a/include/asm-x86/xen/page.h b/include/asm-x86/xen/page.h
--- a/include/asm-x86/xen/page.h
+++ b/include/asm-x86/xen/page.h
@@ -26,15 +26,15 @@
#define FOREIGN_FRAME_BIT (1UL<<31)
#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
-extern unsigned long *phys_to_machine_mapping;
+extern unsigned long get_phys_to_machine(unsigned long pfn);
+extern void set_phys_to_machine(unsigned long pfn, unsigned long mfn);
static inline unsigned long pfn_to_mfn(unsigned long pfn)
{
if (xen_feature(XENFEAT_auto_translated_physmap))
return pfn;
- return phys_to_machine_mapping[(unsigned int)(pfn)] &
- ~FOREIGN_FRAME_BIT;
+ return get_phys_to_machine(pfn) & ~FOREIGN_FRAME_BIT;
}
static inline int phys_to_machine_mapping_valid(unsigned long pfn)
@@ -42,7 +42,7 @@
if (xen_feature(XENFEAT_auto_translated_physmap))
return 1;
- return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+ return get_phys_to_machine(pfn) != INVALID_P2M_ENTRY;
}
static inline unsigned long mfn_to_pfn(unsigned long mfn)
@@ -106,18 +106,10 @@
unsigned long pfn = mfn_to_pfn(mfn);
if ((pfn < max_mapnr)
&& !xen_feature(XENFEAT_auto_translated_physmap)
- && (phys_to_machine_mapping[pfn] != mfn))
+ && (get_phys_to_machine(pfn) != mfn))
return max_mapnr; /* force !pfn_valid() */
+ /* XXX fixme; not true with sparsemem */
return pfn;
-}
-
-static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
-{
- if (xen_feature(XENFEAT_auto_translated_physmap)) {
- BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
- return;
- }
- phys_to_machine_mapping[pfn] = mfn;
}
/* VIRT <-> MACHINE conversion */
next prev parent reply other threads:[~2008-04-04 0:18 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-04 0:05 [PATCH 0 of 6] [RFC] another attempt at making hotplug memory and xen play together Jeremy Fitzhardinge
2008-04-04 0:05 ` [PATCH 1 of 6] hotplug-memory: refactor online_pages to separate zone growth from page onlining Jeremy Fitzhardinge
2008-04-04 1:06 ` Dave Hansen
2008-04-04 1:20 ` Jeremy Fitzhardinge
2008-04-04 1:33 ` Dave Hansen
2008-04-04 1:09 ` Dave Hansen
2008-04-04 1:32 ` Jeremy Fitzhardinge
2008-04-04 1:41 ` Dave Hansen
2008-04-04 1:56 ` Yasunori Goto
2008-04-04 5:34 ` Jeremy Fitzhardinge
2008-04-04 0:05 ` Jeremy Fitzhardinge [this message]
2008-04-04 0:05 ` [PATCH 3 of 6] xen-balloon: use memory hot-add to expand the domain's memory Jeremy Fitzhardinge
2008-04-04 0:05 ` [PATCH 4 of 6] hotplug-memory: use common online_page Jeremy Fitzhardinge
2008-04-04 0:47 ` Dave Hansen
2008-04-04 0:56 ` Jeremy Fitzhardinge
2008-04-04 1:00 ` Dave Hansen
2008-04-04 1:11 ` Jeremy Fitzhardinge
2008-04-04 1:22 ` Dave Hansen
2008-04-04 0:05 ` [PATCH 5 of 6] hotplug-memory: add section_ops Jeremy Fitzhardinge
2008-04-04 0:51 ` Dave Hansen
2008-04-04 1:12 ` Jeremy Fitzhardinge
2008-04-04 1:52 ` Dave Hansen
2008-04-04 5:32 ` Jeremy Fitzhardinge
2008-04-04 14:22 ` Dave Hansen
2008-04-04 18:21 ` Jeremy Fitzhardinge
2008-04-04 19:28 ` Christoph Lameter
2008-04-04 20:38 ` Jeremy Fitzhardinge
2008-04-04 1:47 ` KAMEZAWA Hiroyuki
2008-04-04 5:35 ` Jeremy Fitzhardinge
2008-04-04 0:05 ` [PATCH 6 of 6] xen-balloon: define a section_ops Jeremy Fitzhardinge
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=ba2c061db66983f9415c.1207267542@localhost \
--to=jeremy@goop.org \
--cc=clameter@sgi.com \
--cc=dave@linux.vnet.ibm.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=y-goto@jp.fujitsu.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 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.