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/mm.h | |
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/mm.h')
-rw-r--r-- | xen/include/asm-x86/mm.h | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 26a1a680f2..f1d6c8dc1c 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -214,6 +214,23 @@ struct page_info #define PGC_count_width PG_shift(9) #define PGC_count_mask ((1UL<<PGC_count_width)-1) +#ifdef __x86_64__ +struct spage_info +{ + unsigned long type_info; +}; + + /* The following page types are MUTUALLY EXCLUSIVE. */ +#define SGT_none PG_mask(0, 2) /* superpage not in use */ +#define SGT_mark PG_mask(1, 2) /* Marked as a superpage */ +#define SGT_dynamic PG_mask(2, 2) /* has been dynamically mapped as a superpage */ +#define SGT_type_mask PG_mask(3, 2) /* Bits 30-31 or 62-63. */ + + /* Count of uses of this superpage as its current type. */ +#define SGT_count_width PG_shift(3) +#define SGT_count_mask ((1UL<<SGT_count_width)-1) +#endif + #if defined(__i386__) #define is_xen_heap_page(page) is_xen_heap_mfn(page_to_mfn(page)) #define is_xen_heap_mfn(mfn) ({ \ @@ -262,6 +279,9 @@ extern void share_xen_page_with_privileged_guests( struct page_info *page, int readonly); #define frame_table ((struct page_info *)FRAMETABLE_VIRT_START) +#ifdef __x86_64__ +#define spage_table ((struct spage_info *)SPAGETABLE_VIRT_START) +#endif extern unsigned long max_page; extern unsigned long total_pages; void init_frametable(void); @@ -305,6 +325,8 @@ void cleanup_page_cacheattr(struct page_info *page); int is_iomem_page(unsigned long mfn); +void clear_superpage_mark(struct page_info *page); + struct domain *page_get_owner_and_reference(struct page_info *page); void put_page(struct page_info *page); int get_page(struct page_info *page, struct domain *domain); @@ -370,7 +392,7 @@ pae_copy_root(struct vcpu *v, l3_pgentry_t *l3tab); int check_descriptor(const struct domain *, struct desc_struct *d); -extern int opt_allow_hugepage; +extern int opt_allow_superpage; extern int mem_hotplug; /****************************************************************************** |