diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-05-27 09:04:46 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-05-27 09:04:46 +0100 |
commit | 06ef473029dcd540b7e4fb76f89cc54fd53a840e (patch) | |
tree | 249c7b6f44168e2d7ee1d631c892e2130e2df2cb /xen/include/asm-x86/x86_64 | |
parent | 92ed5b7e9c642ff0f7c68eb8a39bd687726ba03c (diff) | |
download | xen-06ef473029dcd540b7e4fb76f89cc54fd53a840e.tar.gz xen-06ef473029dcd540b7e4fb76f89cc54fd53a840e.tar.bz2 xen-06ef473029dcd540b7e4fb76f89cc54fd53a840e.zip |
x86: Speed up PV-guest superpage mapping
The current version of superpage mapping takes a PGT_writable
reference to every page in a superpage each time it is mapped. This
is extremely slow, so slow that applications become unusable.
My solution for this is to introduce a superpage table in the
hypervisor, similar to the frametable structure for pages. Currently
this table only has a type_info element. There are three types a
superpage can have, SGT_mark, SGT_dynamic, or SGT_none.
In normal operation, the first time a superpage is mapped, a
PGT_writable reference is taken to each page in the superpage, and the
superpage is set to type SGT_dynamic and the superpage typecount is
incremented. On subsequent mappings and unmappings, only the
superpage typecount changes. On the last unmap, the PGT_writable
reference on each page is removed.
The SGT_mark type is set and cleared through two new MMUEXT
hypercalls, mark_super and unmark_super. When the hypercall is made,
the superpage's type is set to SGT_mark and a PGT_writable reference
is taken to its pages. On unmark, the type is cleared and the
reference removed.
If a page is already set to SGT_dynamic when mark_super is called, the
type is changed to SGT_mark and no additional PGT_writable reference
is taken. If there are still outstanding mappings of this superpage
when unmark_super is called, the type is set to SGT_dynamic and the
PGT_writable reference is not removed.
Fast superpage mapping is only supported on 64 bit hypervisors. For
32 bit hyperviors, superpage mapping is supported but will be
extremely slow.
Signed-off-by: Dave McCracken <dave.mccracken@oracle.com>
Diffstat (limited to 'xen/include/asm-x86/x86_64')
-rw-r--r-- | xen/include/asm-x86/x86_64/page.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h index f1448c12a8..2e61709e29 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h @@ -7,6 +7,7 @@ #define L3_PAGETABLE_SHIFT 30 #define L4_PAGETABLE_SHIFT 39 #define PAGE_SHIFT L1_PAGETABLE_SHIFT +#define SUPERPAGE_SHIFT L2_PAGETABLE_SHIFT #define ROOT_PAGETABLE_SHIFT L4_PAGETABLE_SHIFT #define PAGETABLE_ORDER 9 @@ -15,6 +16,7 @@ #define L3_PAGETABLE_ENTRIES (1<<PAGETABLE_ORDER) #define L4_PAGETABLE_ENTRIES (1<<PAGETABLE_ORDER) #define ROOT_PAGETABLE_ENTRIES L4_PAGETABLE_ENTRIES +#define SUPERPAGE_ORDER PAGETABLE_ORDER #define __PAGE_OFFSET DIRECTMAP_VIRT_START #define __XEN_VIRT_START XEN_VIRT_START @@ -41,6 +43,8 @@ extern void pfn_pdx_hole_setup(unsigned long); #define page_to_pdx(pg) ((pg) - frame_table) #define pdx_to_page(pdx) (frame_table + (pdx)) +#define spage_to_pdx(spg) ((spg>>(SUPERPAGE_SHIFT-PAGE_SHIFT)) - spage_table) +#define pdx_to_spage(pdx) (spage_table + ((pdx)<<(SUPERPAGE_SHIFT-PAGE_SHIFT))) /* * Note: These are solely for the use by page_{get,set}_owner(), and * therefore don't need to handle the XEN_VIRT_{START,END} range. @@ -64,6 +68,16 @@ static inline unsigned long pdx_to_pfn(unsigned long pdx) ((pdx << pfn_pdx_hole_shift) & pfn_top_mask); } +static inline unsigned long pfn_to_sdx(unsigned long pfn) +{ + return pfn_to_pdx(pfn) >> (SUPERPAGE_SHIFT-PAGE_SHIFT); +} + +static inline unsigned long sdx_to_pfn(unsigned long sdx) +{ + return pdx_to_pfn(sdx << (SUPERPAGE_SHIFT-PAGE_SHIFT)); +} + static inline unsigned long __virt_to_maddr(unsigned long va) { ASSERT(va >= XEN_VIRT_START); |