Skip to contentSkip to conversation

PV hugepages - Linux patch

PATCH In review Dave McCracken 1 participant 1 message Oct 2, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 2/2 PV hugepages - Linux patch

This patch enables support of hugepages in a pv Xen environment. It is against the latest linux-2.6.18-xen tree on http://xenbits.xensource.com.

The patch assumes the guest memory was contiguously allocated on a hugepage-aligned boundary. Future versions of the patch may include checking the hugepage pool and removing hugepages that are not properly aligned.

Dave McCracken
Oracle Corp.

./fs/Kconfig renamed from /./fs/Kconfig +1 -1
@@ -870,7 +870,7 @@ config TMPFS
 config HUGETLBFS
 	bool "HugeTLB file system support"
 	depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
-	depends on !XEN
+#	depends on !XEN
 	help
 	  hugetlbfs is a filesystem backing for HugeTLB pages, based on
 	  ramfs. For architectures that support it, say Y here and read
./include/asm-x86_64/mach-xen/asm/page.h renamed from /./include/asm-x86_64/mach-xen/asm/page.h +2 -0
@@ -62,6 +62,8 @@
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
 
+#define ARCH_HAS_SETCLEAR_HUGE_PTE
+
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
./include/asm-x86_64/mach-xen/asm/pgtable.h renamed from /./include/asm-x86_64/mach-xen/asm/pgtable.h +19 -0
@@ -261,6 +261,12 @@ static inline unsigned long pud_bad(pud_
 		set_pte((ptep), (pteval));				\
 } while (0)
 
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval) {
+	if ((mm != current->mm && mm != &init_mm) ||
+	    HYPERVISOR_update_va_mapping(addr, pteval, 0))
+		set_pmd((pmd_t *)ptep, (pmd_t){__pte_val(pteval)});
+}
+
 #define pte_none(x)	(!(x).pte)
 #define pte_present(x)	((x).pte & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(mm,addr,xp)	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
@@ -296,6 +302,19 @@ static inline pte_t ptep_get_and_clear(s
 	return pte;
 }
 
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	if (!pte_none(pte)) {
+		if ((mm != &init_mm) ||
+		    HYPERVISOR_update_va_mapping(addr, __pte(0), 0)) {
+			pte = *ptep;
+			set_pmd((pmd_t *)ptep, __pmd(0));
+		}
+	}
+	return pte;
+}
+
 static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
 {
 	if (full) {
./arch/x86_64/mm/pageattr-xen.c renamed from /./arch/x86_64/mm/pageattr-xen.c +2 -0
@@ -62,6 +62,8 @@ static void _pin_lock(struct mm_struct *
 
 					if (pmd_none(*pmd))
 						continue;
+					if (pte_huge(*(pte_t *)pmd))
+						continue;
 					ptl = pte_lockptr(0, pmd);
 					if (lock)
 						spin_lock(ptl);
./mm/hugetlb.c renamed from /./mm/hugetlb.c +4 -2
@@ -294,12 +294,14 @@ static pte_t make_huge_pte(struct vm_are
 				int writable)
 {
 	pte_t entry;
+	pgprot_t pgprot;
 
+	pgprot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_PRESENT);
 	if (writable) {
 		entry =
-		    pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+		    pte_mkwrite(pte_mkdirty(mk_pte(page, pgprot)));
 	} else {
-		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
+		entry = pte_wrprotect(mk_pte(page, pgprot));
 	}
 	entry = pte_mkyoung(entry);
 	entry = pte_mkhuge(entry);

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel