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-changelog

[Xen-changelog] [xen-unstable] linux/i386: relax highpte pinning/write-p

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] linux/i386: relax highpte pinning/write-protecting
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 22 Jan 2007 11:00:15 -0800
Delivery-date: Mon, 22 Jan 2007 11:00:18 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1169480533 0
# Node ID 765e08679f2b197b8a7384f76503e74dbee61c7f
# Parent  de6c4f72b65bf0bb06adc458ae223285c92241d9
linux/i386: relax highpte pinning/write-protecting
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
 linux-2.6-xen-sparse/include/xen/foreign_page.h              |   30 -
 linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c              |    4 
 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c              |   60 +-
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h    |   13 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h |   22 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h |    3 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h  |   13 
 linux-2.6-xen-sparse/include/linux/page-flags.h              |  280 +++++++++++
 linux-2.6-xen-sparse/mm/page_alloc.c                         |   18 
 9 files changed, 348 insertions(+), 95 deletions(-)

diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c   Mon Jan 22 15:31:27 
2007 +0000
+++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c   Mon Jan 22 15:42:13 
2007 +0000
@@ -55,7 +55,9 @@ void *kmap_atomic(struct page *page, enu
 /* Same as kmap_atomic but with PAGE_KERNEL_RO page protection. */
 void *kmap_atomic_pte(struct page *page, enum km_type type)
 {
-       return __kmap_atomic(page, type, PAGE_KERNEL_RO);
+       return __kmap_atomic(page, type,
+                            test_bit(PG_pinned, &page->flags)
+                            ? PAGE_KERNEL_RO : kmap_prot);
 }
 
 void kunmap_atomic(void *kvaddr, enum km_type type)
diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Mon Jan 22 15:31:27 
2007 +0000
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Mon Jan 22 15:42:13 
2007 +0000
@@ -25,7 +25,6 @@
 #include <asm/mmu_context.h>
 
 #include <xen/features.h>
-#include <xen/foreign_page.h>
 #include <asm/hypervisor.h>
 
 static void pgd_test_and_unpin(pgd_t *pgd);
@@ -239,14 +238,6 @@ 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
@@ -267,13 +258,8 @@ void pte_free(struct page *pte)
                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);
-       }
+       } else
+               clear_bit(PG_pinned, &pte->flags);
 
        ClearPageForeign(pte);
        init_page_count(pte);
@@ -587,46 +573,48 @@ void make_pages_writable(void *va, unsig
        }
 }
 
-static inline void pgd_walk_set_prot(void *pt, pgprot_t flags)
-{
-       struct page *page = virt_to_page(pt);
+static inline int pgd_walk_set_prot(struct page *page, pgprot_t flags)
+{
        unsigned long pfn = page_to_pfn(page);
 
        if (PageHighMem(page))
-               return;
+               return pgprot_val(flags) & _PAGE_RW
+                      ? test_and_clear_bit(PG_pinned, &page->flags)
+                      : !test_and_set_bit(PG_pinned, &page->flags);
+
        BUG_ON(HYPERVISOR_update_va_mapping(
                (unsigned long)__va(pfn << PAGE_SHIFT),
                pfn_pte(pfn, flags), 0));
-}
-
-static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
+
+       return 0;
+}
+
+static int pgd_walk(pgd_t *pgd_base, pgprot_t flags)
 {
        pgd_t *pgd = pgd_base;
        pud_t *pud;
        pmd_t *pmd;
-       pte_t *pte;
-       int    g, u, m;
+       int    g, u, m, flush;
 
        if (xen_feature(XENFEAT_auto_translated_physmap))
-               return;
-
-       for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
+               return 0;
+
+       for (g = 0, flush = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
                if (pgd_none(*pgd))
                        continue;
                pud = pud_offset(pgd, 0);
                if (PTRS_PER_PUD > 1) /* not folded */
-                       pgd_walk_set_prot(pud,flags);
+                       flush |= pgd_walk_set_prot(virt_to_page(pud),flags);
                for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
                        if (pud_none(*pud))
                                continue;
                        pmd = pmd_offset(pud, 0);
                        if (PTRS_PER_PMD > 1) /* not folded */
-                               pgd_walk_set_prot(pmd,flags);
+                               flush |= 
pgd_walk_set_prot(virt_to_page(pmd),flags);
                        for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
                                if (pmd_none(*pmd))
                                        continue;
-                               pte = pte_offset_kernel(pmd,0);
-                               pgd_walk_set_prot(pte,flags);
+                               flush |= 
pgd_walk_set_prot(pmd_page(*pmd),flags);
                        }
                }
        }
@@ -635,11 +623,14 @@ static void pgd_walk(pgd_t *pgd_base, pg
                (unsigned long)pgd_base,
                pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
                UVMF_TLB_FLUSH));
+
+       return flush;
 }
 
 static void __pgd_pin(pgd_t *pgd)
 {
-       pgd_walk(pgd, PAGE_KERNEL_RO);
+       if (pgd_walk(pgd, PAGE_KERNEL_RO))
+               kmap_flush_unused();
        xen_pgd_pin(__pa(pgd));
        set_bit(PG_pinned, &virt_to_page(pgd)->flags);
 }
@@ -647,7 +638,8 @@ static void __pgd_unpin(pgd_t *pgd)
 static void __pgd_unpin(pgd_t *pgd)
 {
        xen_pgd_unpin(__pa(pgd));
-       pgd_walk(pgd, PAGE_KERNEL);
+       if (pgd_walk(pgd, PAGE_KERNEL))
+               kmap_flush_unused();
        clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
 }
 
diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon Jan 22 
15:31:27 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon Jan 22 
15:42:13 2007 +0000
@@ -28,13 +28,12 @@
 #include <asm/bug.h>
 #include <xen/interface/xen.h>
 #include <xen/features.h>
-#include <xen/foreign_page.h>
-
-#define arch_free_page(_page,_order)                   \
-({     int foreign = PageForeign(_page);               \
-       if (foreign)                                    \
-               (PageForeignDestructor(_page))(_page);  \
-       foreign;                                        \
+
+#define arch_free_page(_page,_order)           \
+({     int foreign = PageForeign(_page);       \
+       if (foreign)                            \
+               PageForeignDestructor(_page);   \
+       foreign;                                \
 })
 #define HAVE_ARCH_FREE_PAGE
 
diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h      Mon Jan 
22 15:31:27 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h      Mon Jan 
22 15:42:13 2007 +0000
@@ -6,27 +6,23 @@
 #include <linux/mm.h>          /* for struct page */
 #include <asm/io.h>            /* for phys_to_virt and page_to_pseudophys */
 
-/* Is this pagetable pinned? */
-#define PG_pinned      PG_arch_1
-
 #define pmd_populate_kernel(mm, pmd, pte) \
                set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
 
 #define pmd_populate(mm, pmd, pte)                                     \
 do {                                                                   \
+       unsigned long pfn = page_to_pfn(pte);                           \
        if (test_bit(PG_pinned, &virt_to_page((mm)->pgd)->flags)) {     \
                if (!PageHighMem(pte))                                  \
                        BUG_ON(HYPERVISOR_update_va_mapping(            \
-                         (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT),\
-                         pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));\
-               set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
-                       ((unsigned long long)page_to_pfn(pte) <<        \
-                               (unsigned long long) PAGE_SHIFT)));     \
-       } else {                                                        \
-               *(pmd) = __pmd(_PAGE_TABLE +                            \
-                       ((unsigned long long)page_to_pfn(pte) <<        \
-                               (unsigned long long) PAGE_SHIFT));      \
-       }                                                               \
+                         (unsigned long)__va(pfn << PAGE_SHIFT),       \
+                         pfn_pte(pfn, PAGE_KERNEL_RO), 0));            \
+               else if (!test_and_set_bit(PG_pinned, &pte->flags))     \
+                       kmap_flush_unused();                            \
+               set_pmd(pmd,                                            \
+                       __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT))); \
+       } else                                                  \
+               *(pmd) = __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT)); \
 } while (0)
 
 /*
diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h      Mon Jan 
22 15:31:27 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h      Mon Jan 
22 15:42:13 2007 +0000
@@ -24,6 +24,9 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+
+/* Is this pagetable pinned? */
+#define PG_pinned      PG_arch_1
 
 struct mm_struct;
 struct vm_area_struct;
diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h       Mon Jan 
22 15:31:27 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h       Mon Jan 
22 15:42:13 2007 +0000
@@ -8,13 +8,12 @@
 #include <asm/bug.h>
 #endif
 #include <xen/interface/xen.h> 
-#include <xen/foreign_page.h>
-
-#define arch_free_page(_page,_order)                   \
-({     int foreign = PageForeign(_page);               \
-       if (foreign)                                    \
-               (PageForeignDestructor(_page))(_page);  \
-       foreign;                                        \
+
+#define arch_free_page(_page,_order)           \
+({     int foreign = PageForeign(_page);       \
+       if (foreign)                            \
+               PageForeignDestructor(_page);   \
+       foreign;                                \
 })
 #define HAVE_ARCH_FREE_PAGE
 
diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/include/linux/page-flags.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/include/linux/page-flags.h   Mon Jan 22 15:42:13 
2007 +0000
@@ -0,0 +1,280 @@
+/*
+ * Macros for manipulating and testing page->flags
+ */
+
+#ifndef PAGE_FLAGS_H
+#define PAGE_FLAGS_H
+
+#include <linux/types.h>
+
+/*
+ * Various page->flags bits:
+ *
+ * PG_reserved is set for special pages, which can never be swapped out. Some
+ * of them might not even exist (eg empty_bad_page)...
+ *
+ * The PG_private bitflag is set if page->private contains a valid value.
+ *
+ * During disk I/O, PG_locked is used. This bit is set before I/O and
+ * reset when I/O completes. page_waitqueue(page) is a wait queue of all tasks
+ * waiting for the I/O on this page to complete.
+ *
+ * PG_uptodate tells whether the page's contents is valid.  When a read
+ * completes, the page becomes uptodate, unless a disk I/O error happened.
+ *
+ * For choosing which pages to swap out, inode pages carry a PG_referenced bit,
+ * which is set any time the system accesses that page through the (mapping,
+ * index) hash table.  This referenced bit, together with the referenced bit
+ * in the page tables, is used to manipulate page->age and move the page across
+ * the active, inactive_dirty and inactive_clean lists.
+ *
+ * Note that the referenced bit, the page->lru list_head and the active,
+ * inactive_dirty and inactive_clean lists are protected by the
+ * zone->lru_lock, and *NOT* by the usual PG_locked bit!
+ *
+ * PG_error is set to indicate that an I/O error occurred on this page.
+ *
+ * PG_arch_1 is an architecture specific page state bit.  The generic code
+ * guarantees that this bit is cleared for a page when it first is entered into
+ * the page cache.
+ *
+ * PG_highmem pages are not permanently mapped into the kernel virtual address
+ * space, they need to be kmapped separately for doing IO on the pages.  The
+ * struct page (these bits with information) are always mapped into kernel
+ * address space...
+ */
+
+/*
+ * Don't use the *_dontuse flags.  Use the macros.  Otherwise you'll break
+ * locked- and dirty-page accounting.
+ *
+ * The page flags field is split into two parts, the main flags area
+ * which extends from the low bits upwards, and the fields area which
+ * extends from the high bits downwards.
+ *
+ *  | FIELD | ... | FLAGS |
+ *  N-1     ^             0
+ *          (N-FLAGS_RESERVED)
+ *
+ * The fields area is reserved for fields mapping zone, node and SPARSEMEM
+ * section.  The boundry between these two areas is defined by
+ * FLAGS_RESERVED which defines the width of the fields section
+ * (see linux/mmzone.h).  New flags must _not_ overlap with this area.
+ */
+#define PG_locked               0      /* Page is locked. Don't touch. */
+#define PG_error                1
+#define PG_referenced           2
+#define PG_uptodate             3
+
+#define PG_dirty                4
+#define PG_lru                  5
+#define PG_active               6
+#define PG_slab                         7      /* slab debug (Suparna wants 
this) */
+
+#define PG_checked              8      /* kill me in 2.5.<early>. */
+#define PG_arch_1               9
+#define PG_reserved            10
+#define PG_private             11      /* Has something at ->private */
+
+#define PG_writeback           12      /* Page is under writeback */
+#define PG_nosave              13      /* Used for system suspend/resume */
+#define PG_compound            14      /* Part of a compound page */
+#define PG_swapcache           15      /* Swap page: swp_entry_t in private */
+
+#define PG_mappedtodisk                16      /* Has blocks allocated on-disk 
*/
+#define PG_reclaim             17      /* To be reclaimed asap */
+#define PG_nosave_free         18      /* Free, should not be written */
+#define PG_buddy               19      /* Page is free, on buddy lists */
+
+
+#if (BITS_PER_LONG > 32)
+/*
+ * 64-bit-only flags build down from bit 31
+ *
+ * 32 bit  -------------------------------| FIELDS |       FLAGS         |
+ * 64 bit  |           FIELDS             | ??????         FLAGS         |
+ *         63                            32                              0
+ */
+#define PG_uncached            31      /* Page has been mapped as uncached */
+#endif
+
+#define PG_foreign             20      /* Page is owned by foreign allocator. 
*/
+
+/*
+ * Manipulation of page state flags
+ */
+#define PageLocked(page)               \
+               test_bit(PG_locked, &(page)->flags)
+#define SetPageLocked(page)            \
+               set_bit(PG_locked, &(page)->flags)
+#define TestSetPageLocked(page)                \
+               test_and_set_bit(PG_locked, &(page)->flags)
+#define ClearPageLocked(page)          \
+               clear_bit(PG_locked, &(page)->flags)
+#define TestClearPageLocked(page)      \
+               test_and_clear_bit(PG_locked, &(page)->flags)
+
+#define PageError(page)                test_bit(PG_error, &(page)->flags)
+#define SetPageError(page)     set_bit(PG_error, &(page)->flags)
+#define ClearPageError(page)   clear_bit(PG_error, &(page)->flags)
+
+#define PageReferenced(page)   test_bit(PG_referenced, &(page)->flags)
+#define SetPageReferenced(page)        set_bit(PG_referenced, &(page)->flags)
+#define ClearPageReferenced(page)      clear_bit(PG_referenced, &(page)->flags)
+#define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, 
&(page)->flags)
+
+#define PageUptodate(page)     test_bit(PG_uptodate, &(page)->flags)
+#ifdef CONFIG_S390
+#define SetPageUptodate(_page) \
+       do {                                                                  \
+               struct page *__page = (_page);                                \
+               if (!test_and_set_bit(PG_uptodate, &__page->flags))           \
+                       page_test_and_clear_dirty(_page);                     \
+       } while (0)
+#else
+#define SetPageUptodate(page)  set_bit(PG_uptodate, &(page)->flags)
+#endif
+#define ClearPageUptodate(page)        clear_bit(PG_uptodate, &(page)->flags)
+
+#define PageDirty(page)                test_bit(PG_dirty, &(page)->flags)
+#define SetPageDirty(page)     set_bit(PG_dirty, &(page)->flags)
+#define TestSetPageDirty(page) test_and_set_bit(PG_dirty, &(page)->flags)
+#define ClearPageDirty(page)   clear_bit(PG_dirty, &(page)->flags)
+#define __ClearPageDirty(page) __clear_bit(PG_dirty, &(page)->flags)
+#define TestClearPageDirty(page) test_and_clear_bit(PG_dirty, &(page)->flags)
+
+#define PageLRU(page)          test_bit(PG_lru, &(page)->flags)
+#define SetPageLRU(page)       set_bit(PG_lru, &(page)->flags)
+#define ClearPageLRU(page)     clear_bit(PG_lru, &(page)->flags)
+#define __ClearPageLRU(page)   __clear_bit(PG_lru, &(page)->flags)
+
+#define PageActive(page)       test_bit(PG_active, &(page)->flags)
+#define SetPageActive(page)    set_bit(PG_active, &(page)->flags)
+#define ClearPageActive(page)  clear_bit(PG_active, &(page)->flags)
+#define __ClearPageActive(page)        __clear_bit(PG_active, &(page)->flags)
+
+#define PageSlab(page)         test_bit(PG_slab, &(page)->flags)
+#define __SetPageSlab(page)    __set_bit(PG_slab, &(page)->flags)
+#define __ClearPageSlab(page)  __clear_bit(PG_slab, &(page)->flags)
+
+#ifdef CONFIG_HIGHMEM
+#define PageHighMem(page)      is_highmem(page_zone(page))
+#else
+#define PageHighMem(page)      0 /* needed to optimize away at compile time */
+#endif
+
+#define PageChecked(page)      test_bit(PG_checked, &(page)->flags)
+#define SetPageChecked(page)   set_bit(PG_checked, &(page)->flags)
+#define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags)
+
+#define PageReserved(page)     test_bit(PG_reserved, &(page)->flags)
+#define SetPageReserved(page)  set_bit(PG_reserved, &(page)->flags)
+#define ClearPageReserved(page)        clear_bit(PG_reserved, &(page)->flags)
+#define __ClearPageReserved(page)      __clear_bit(PG_reserved, &(page)->flags)
+
+#define SetPagePrivate(page)   set_bit(PG_private, &(page)->flags)
+#define ClearPagePrivate(page) clear_bit(PG_private, &(page)->flags)
+#define PagePrivate(page)      test_bit(PG_private, &(page)->flags)
+#define __SetPagePrivate(page)  __set_bit(PG_private, &(page)->flags)
+#define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags)
+
+#define PageWriteback(page)    test_bit(PG_writeback, &(page)->flags)
+#define SetPageWriteback(page)                                         \
+       do {                                                            \
+               if (!test_and_set_bit(PG_writeback,                     \
+                               &(page)->flags))                        \
+                       inc_zone_page_state(page, NR_WRITEBACK);        \
+       } while (0)
+#define TestSetPageWriteback(page)                                     \
+       ({                                                              \
+               int ret;                                                \
+               ret = test_and_set_bit(PG_writeback,                    \
+                                       &(page)->flags);                \
+               if (!ret)                                               \
+                       inc_zone_page_state(page, NR_WRITEBACK);        \
+               ret;                                                    \
+       })
+#define ClearPageWriteback(page)                                       \
+       do {                                                            \
+               if (test_and_clear_bit(PG_writeback,                    \
+                               &(page)->flags))                        \
+                       dec_zone_page_state(page, NR_WRITEBACK);        \
+       } while (0)
+#define TestClearPageWriteback(page)                                   \
+       ({                                                              \
+               int ret;                                                \
+               ret = test_and_clear_bit(PG_writeback,                  \
+                               &(page)->flags);                        \
+               if (ret)                                                \
+                       dec_zone_page_state(page, NR_WRITEBACK);        \
+               ret;                                                    \
+       })
+
+#define PageNosave(page)       test_bit(PG_nosave, &(page)->flags)
+#define SetPageNosave(page)    set_bit(PG_nosave, &(page)->flags)
+#define TestSetPageNosave(page)        test_and_set_bit(PG_nosave, 
&(page)->flags)
+#define ClearPageNosave(page)          clear_bit(PG_nosave, &(page)->flags)
+#define TestClearPageNosave(page)      test_and_clear_bit(PG_nosave, 
&(page)->flags)
+
+#define PageNosaveFree(page)   test_bit(PG_nosave_free, &(page)->flags)
+#define SetPageNosaveFree(page)        set_bit(PG_nosave_free, &(page)->flags)
+#define ClearPageNosaveFree(page)              clear_bit(PG_nosave_free, 
&(page)->flags)
+
+#define PageBuddy(page)                test_bit(PG_buddy, &(page)->flags)
+#define __SetPageBuddy(page)   __set_bit(PG_buddy, &(page)->flags)
+#define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags)
+
+#define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags)
+#define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
+#define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
+
+#define PageReclaim(page)      test_bit(PG_reclaim, &(page)->flags)
+#define SetPageReclaim(page)   set_bit(PG_reclaim, &(page)->flags)
+#define ClearPageReclaim(page) clear_bit(PG_reclaim, &(page)->flags)
+#define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, 
&(page)->flags)
+
+#define PageCompound(page)     test_bit(PG_compound, &(page)->flags)
+#define __SetPageCompound(page)        __set_bit(PG_compound, &(page)->flags)
+#define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags)
+
+#ifdef CONFIG_SWAP
+#define PageSwapCache(page)    test_bit(PG_swapcache, &(page)->flags)
+#define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags)
+#define ClearPageSwapCache(page) clear_bit(PG_swapcache, &(page)->flags)
+#else
+#define PageSwapCache(page)    0
+#endif
+
+#define PageUncached(page)     test_bit(PG_uncached, &(page)->flags)
+#define SetPageUncached(page)  set_bit(PG_uncached, &(page)->flags)
+#define ClearPageUncached(page)        clear_bit(PG_uncached, &(page)->flags)
+
+#define PageForeign(page)      test_bit(PG_foreign, &(page)->flags)
+#define SetPageForeign(page, dtor) do {                \
+       set_bit(PG_foreign, &(page)->flags);    \
+       (page)->mapping = (void *)dtor;         \
+} while (0)
+#define ClearPageForeign(page) do {            \
+       clear_bit(PG_foreign, &(page)->flags);  \
+       (page)->mapping = NULL;                 \
+} while (0)
+#define PageForeignDestructor(page)            \
+       ( (void (*) (struct page *)) (page)->mapping )(page)
+
+struct page;   /* forward declaration */
+
+int test_clear_page_dirty(struct page *page);
+int test_clear_page_writeback(struct page *page);
+int test_set_page_writeback(struct page *page);
+
+static inline void clear_page_dirty(struct page *page)
+{
+       test_clear_page_dirty(page);
+}
+
+static inline void set_page_writeback(struct page *page)
+{
+       test_set_page_writeback(page);
+}
+
+#endif /* PAGE_FLAGS_H */
diff -r de6c4f72b65b -r 765e08679f2b 
linux-2.6-xen-sparse/include/xen/foreign_page.h
--- a/linux-2.6-xen-sparse/include/xen/foreign_page.h   Mon Jan 22 15:31:27 
2007 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/******************************************************************************
- * foreign_page.h
- * 
- * Provide a "foreign" page type, that is owned by a foreign allocator and 
- * not the normal buddy allocator in page_alloc.c
- * 
- * Copyright (c) 2004, K A Fraser
- */
-
-#ifndef __ASM_XEN_FOREIGN_PAGE_H__
-#define __ASM_XEN_FOREIGN_PAGE_H__
-
-#define PG_foreign             PG_arch_1
-
-#define PageForeign(page)      test_bit(PG_foreign, &(page)->flags)
-
-#define SetPageForeign(page, dtor) do {                \
-       set_bit(PG_foreign, &(page)->flags);    \
-       (page)->mapping = (void *)dtor;         \
-} while (0)
-
-#define ClearPageForeign(page) do {            \
-       clear_bit(PG_foreign, &(page)->flags);  \
-       (page)->mapping = NULL;                 \
-} while (0)
-
-#define PageForeignDestructor(page)    \
-       ( (void (*) (struct page *)) (page)->mapping )
-
-#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
diff -r de6c4f72b65b -r 765e08679f2b linux-2.6-xen-sparse/mm/page_alloc.c
--- a/linux-2.6-xen-sparse/mm/page_alloc.c      Mon Jan 22 15:31:27 2007 +0000
+++ b/linux-2.6-xen-sparse/mm/page_alloc.c      Mon Jan 22 15:42:13 2007 +0000
@@ -154,7 +154,11 @@ static void bad_page(struct page *page)
                        1 << PG_slab    |
                        1 << PG_swapcache |
                        1 << PG_writeback |
-                       1 << PG_buddy );
+                       1 << PG_buddy   |
+#ifdef CONFIG_X86_XEN
+                       1 << PG_pinned  |
+#endif
+                       1 << PG_foreign );
        set_page_count(page, 0);
        reset_page_mapcount(page);
        page->mapping = NULL;
@@ -389,7 +393,11 @@ static inline int free_pages_check(struc
                        1 << PG_swapcache |
                        1 << PG_writeback |
                        1 << PG_reserved |
-                       1 << PG_buddy ))))
+                       1 << PG_buddy   |
+#ifdef CONFIG_X86_XEN
+                       1 << PG_pinned  |
+#endif
+                       1 << PG_foreign ))))
                bad_page(page);
        if (PageDirty(page))
                __ClearPageDirty(page);
@@ -539,7 +547,11 @@ static int prep_new_page(struct page *pa
                        1 << PG_swapcache |
                        1 << PG_writeback |
                        1 << PG_reserved |
-                       1 << PG_buddy ))))
+                       1 << PG_buddy   |
+#ifdef CONFIG_X86_XEN
+                       1 << PG_pinned  |
+#endif
+                       1 << PG_foreign ))))
                bad_page(page);
 
        /*

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] linux/i386: relax highpte pinning/write-protecting, Xen patchbot-unstable <=