While, as discussed, the performance impact of this option is certainly higher
than on native Linux, the option should not be entirely disallowed if people
want to sacrifice performance for less lowmem pressure.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Index: sle10-sp1-2007-01-10/arch/i386/Kconfig
===================================================================
--- sle10-sp1-2007-01-10.orig/arch/i386/Kconfig 2007-01-10 13:33:54.000000000
+0100
+++ sle10-sp1-2007-01-10/arch/i386/Kconfig 2007-01-09 11:47:18.000000000
+0100
@@ -594,7 +594,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
config HIGHPTE
bool "Allocate 3rd-level pagetables from highmem"
- depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN
+ depends on HIGHMEM4G || HIGHMEM64G
help
The VM uses one page table entry for each page of physical memory.
For systems with a lot of RAM, this can be wasteful of precious
Index: sle10-sp1-2007-01-10/arch/i386/mm/highmem-xen.c
===================================================================
--- sle10-sp1-2007-01-10.orig/arch/i386/mm/highmem-xen.c 2007-01-10
13:33:54.000000000 +0100
+++ sle10-sp1-2007-01-10/arch/i386/mm/highmem-xen.c 2007-01-09
12:45:43.000000000 +0100
@@ -129,5 +129,6 @@ struct page *kmap_atomic_to_page(void *p
EXPORT_SYMBOL(kmap);
EXPORT_SYMBOL(kunmap);
EXPORT_SYMBOL(kmap_atomic);
+EXPORT_SYMBOL(kmap_atomic_pte);
EXPORT_SYMBOL(kunmap_atomic);
EXPORT_SYMBOL(kmap_atomic_to_page);
Index: sle10-sp1-2007-01-10/arch/i386/mm/pgtable-xen.c
===================================================================
--- sle10-sp1-2007-01-10.orig/arch/i386/mm/pgtable-xen.c 2007-01-10
13:33:54.000000000 +0100
+++ sle10-sp1-2007-01-10/arch/i386/mm/pgtable-xen.c 2007-01-10
14:14:47.000000000 +0100
@@ -238,23 +238,41 @@ struct page *pte_alloc_one(struct mm_str
#ifdef CONFIG_HIGHPTE
pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
+ if (pte && PageHighMem(pte)) {
+ struct mmuext_op op;
+
+ kmap_flush_unused();
+ op.cmd = MMUEXT_PIN_L1_TABLE;
+ op.arg1.mfn = pfn_to_mfn(page_to_pfn(pte));
+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
+ }
#else
pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
+#endif
if (pte) {
SetPageForeign(pte, pte_free);
set_page_count(pte, 1);
}
-#endif
return pte;
}
void pte_free(struct page *pte)
{
- unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
+ unsigned long pfn = page_to_pfn(pte);
- if (!pte_write(*virt_to_ptep(va)))
- BUG_ON(HYPERVISOR_update_va_mapping(
- va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
+ if (!PageHighMem(pte)) {
+ unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT);
+
+ if (!pte_write(*virt_to_ptep(va)))
+ BUG_ON(HYPERVISOR_update_va_mapping(
+ va, pfn_pte(pfn, PAGE_KERNEL), 0));
+ } else {
+ struct mmuext_op op;
+
+ op.cmd = MMUEXT_UNPIN_TABLE;
+ op.arg1.mfn = pfn_to_mfn(pfn);
+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
+ }
ClearPageForeign(pte);
set_page_count(pte, 1);
Index: sle10-sp1-2007-01-10/include/asm-i386/mach-xen/asm/pgalloc.h
===================================================================
--- sle10-sp1-2007-01-10.orig/include/asm-i386/mach-xen/asm/pgalloc.h
2007-01-10 13:33:54.000000000 +0100
+++ sle10-sp1-2007-01-10/include/asm-i386/mach-xen/asm/pgalloc.h
2007-01-10 14:15:14.000000000 +0100
@@ -42,7 +42,7 @@ extern struct page *pte_alloc_one(struct
static inline void pte_free_kernel(pte_t *pte)
{
free_page((unsigned long)pte);
- make_page_writable(pte, XENFEAT_writable_page_tables);
+ make_lowmem_page_writable(pte, XENFEAT_writable_page_tables);
}
extern void pte_free(struct page *pte);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|