WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] linux/x86-64: sync page table allocation with i386 (

To: "Keir Fraser" <keir@xxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] linux/x86-64: sync page table allocation with i386 (was: Re: [PATCH] linux/i386: allow CONFIG_HIGHPTE on i386)
From: "Jan Beulich" <jbeulich@xxxxxxxxxx>
Date: Wed, 10 Jan 2007 15:52:14 +0000
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Wed, 10 Jan 2007 07:50:20 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <C1CA7E6B.7652%keir@xxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <45A4D8A8.76E4.0078.0@xxxxxxxxxx> <C1CA7E6B.7652%keir@xxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
>>> Keir Fraser <keir@xxxxxxxxxxxxx> 10.01.07 12:28 >>>
>On 10/1/07 11:14, "Jan Beulich" <jbeulich@xxxxxxxxxx> wrote:
>
>>> Is it actually safe to circumvent tlb_remove_page()? It does rather more
>>> than just free_page()! That's why I used a ForeignPage hook when writing the
>>> i386 code. It's certainly *not* safe to assume that whoever wrote that part
>>> of the x86/64 port understood all the ramifications of what they were doing.
>> 
>> Not really, as I understand it - it either frees the page (when the TLB is in
>> fast
>> mode) or inserts the page into the gather list, bumping the contained pages
>> count and freeing all of them and flushing the hardware TLBs if exceeding the
>> threshold - the latter step is otherwise done from tlb_finish_mmu().
>
>Presumably this gathering happens because it may not be safe to free the
>pages without having first flushed the TLBs? Freeing the page with no TLB
>flush management at all would be a bad idea in that case.
>
>And I said that sync'ing with i386 is a good general rule. I trust the code
>a lot more. :-)

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

Index: sle10-sp1-2007-01-10/arch/x86_64/mm/pageattr-xen.c
===================================================================
--- sle10-sp1-2007-01-10.orig/arch/x86_64/mm/pageattr-xen.c     2007-01-10 
13:44:37.000000000 +0100
+++ sle10-sp1-2007-01-10/arch/x86_64/mm/pageattr-xen.c  2007-01-10 
14:07:10.000000000 +0100
@@ -164,6 +164,18 @@ void _arch_exit_mmap(struct mm_struct *m
         mm_unpin(mm);
 }
 
+struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+       struct page *pte;
+
+       pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
+       if (pte) {
+               SetPageForeign(pte, pte_free);
+               set_page_count(pte, 1);
+       }
+       return pte;
+}
+
 void pte_free(struct page *pte)
 {
        unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
@@ -171,6 +183,10 @@ void pte_free(struct page *pte)
        if (!pte_write(*virt_to_ptep(va)))
                BUG_ON(HYPERVISOR_update_va_mapping(
                        va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
+
+       ClearPageForeign(pte);
+       set_page_count(pte, 1);
+
        __free_page(pte);
 }
 #endif /* CONFIG_XEN */
Index: sle10-sp1-2007-01-10/include/asm-x86_64/mach-xen/asm/pgalloc.h
===================================================================
--- sle10-sp1-2007-01-10.orig/include/asm-x86_64/mach-xen/asm/pgalloc.h 
2007-01-10 10:09:53.000000000 +0100
+++ sle10-sp1-2007-01-10/include/asm-x86_64/mach-xen/asm/pgalloc.h      
2007-01-10 14:33:04.000000000 +0100
@@ -64,42 +64,35 @@ static inline void pgd_populate(struct m
        }
 }
 
-static inline void pmd_free(pmd_t *pmd)
+extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
+extern void pte_free(struct page *pte);
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-       pte_t *ptep = virt_to_ptep(pmd);
+       struct page *pg;
 
-       if (!pte_write(*ptep)) {
-               BUG_ON(HYPERVISOR_update_va_mapping(
-                       (unsigned long)pmd,
-                       pfn_pte(virt_to_phys(pmd)>>PAGE_SHIFT, PAGE_KERNEL),
-                       0));
-       }
-       free_page((unsigned long)pmd);
+       pg = pte_alloc_one(mm, addr);
+       return pg ? page_address(pg) : NULL;
 }
 
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+static inline void pmd_free(pmd_t *pmd)
 {
-        pmd_t *pmd = (pmd_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
-        return pmd;
+       BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
+       pte_free(virt_to_page(pmd));
 }
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-        pud_t *pud = (pud_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
-        return pud;
+       struct page *pg;
+
+       pg = pte_alloc_one(mm, addr);
+       return pg ? page_address(pg) : NULL;
 }
 
 static inline void pud_free(pud_t *pud)
 {
-       pte_t *ptep = virt_to_ptep(pud);
-
-       if (!pte_write(*ptep)) {
-               BUG_ON(HYPERVISOR_update_va_mapping(
-                       (unsigned long)pud,
-                       pfn_pte(virt_to_phys(pud)>>PAGE_SHIFT, PAGE_KERNEL),
-                       0));
-       }
-       free_page((unsigned long)pud);
+       BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
+       pte_free(virt_to_page(pud));
 }
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
@@ -167,14 +160,6 @@ static inline pte_t *pte_alloc_one_kerne
        return pte;
 }
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long 
address)
-{
-       struct page *pte;
-
-       pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
-       return pte;
-}
-
 /* Should really implement gc for free page table pages. This could be
    done with a reference count in struct page. */
 
@@ -185,14 +170,8 @@ static inline void pte_free_kernel(pte_t
        free_page((unsigned long)pte); 
 }
 
-extern void pte_free(struct page *pte);
-
-//#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) 
-//#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
-//#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
-
-#define __pte_free_tlb(tlb,x)   pte_free((x))
-#define __pmd_free_tlb(tlb,x)   pmd_free((x))
-#define __pud_free_tlb(tlb,x)   pud_free((x))
+#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
+#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
+#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
 
 #endif /* _X86_64_PGALLOC_H */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>