ia64/xen-unstable
changeset 13560:765e08679f2b
linux/i386: relax highpte pinning/write-protecting
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Jan Beulich <jbeulich@novell.com>
author | kfraser@localhost.localdomain |
---|---|
date | Mon Jan 22 15:42:13 2007 +0000 (2007-01-22) |
parents | de6c4f72b65b |
children | cc819d81be2a |
files | linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h linux-2.6-xen-sparse/include/linux/page-flags.h linux-2.6-xen-sparse/include/xen/foreign_page.h linux-2.6-xen-sparse/mm/page_alloc.c |
line diff
1.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c Mon Jan 22 15:31:27 2007 +0000 1.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c Mon Jan 22 15:42:13 2007 +0000 1.3 @@ -55,7 +55,9 @@ void *kmap_atomic(struct page *page, enu 1.4 /* Same as kmap_atomic but with PAGE_KERNEL_RO page protection. */ 1.5 void *kmap_atomic_pte(struct page *page, enum km_type type) 1.6 { 1.7 - return __kmap_atomic(page, type, PAGE_KERNEL_RO); 1.8 + return __kmap_atomic(page, type, 1.9 + test_bit(PG_pinned, &page->flags) 1.10 + ? PAGE_KERNEL_RO : kmap_prot); 1.11 } 1.12 1.13 void kunmap_atomic(void *kvaddr, enum km_type type)
2.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Mon Jan 22 15:31:27 2007 +0000 2.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Mon Jan 22 15:42:13 2007 +0000 2.3 @@ -25,7 +25,6 @@ 2.4 #include <asm/mmu_context.h> 2.5 2.6 #include <xen/features.h> 2.7 -#include <xen/foreign_page.h> 2.8 #include <asm/hypervisor.h> 2.9 2.10 static void pgd_test_and_unpin(pgd_t *pgd); 2.11 @@ -239,14 +238,6 @@ struct page *pte_alloc_one(struct mm_str 2.12 2.13 #ifdef CONFIG_HIGHPTE 2.14 pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0); 2.15 - if (pte && PageHighMem(pte)) { 2.16 - struct mmuext_op op; 2.17 - 2.18 - kmap_flush_unused(); 2.19 - op.cmd = MMUEXT_PIN_L1_TABLE; 2.20 - op.arg1.mfn = pfn_to_mfn(page_to_pfn(pte)); 2.21 - BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); 2.22 - } 2.23 #else 2.24 pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); 2.25 #endif 2.26 @@ -267,13 +258,8 @@ void pte_free(struct page *pte) 2.27 if (!pte_write(*virt_to_ptep(va))) 2.28 BUG_ON(HYPERVISOR_update_va_mapping( 2.29 va, pfn_pte(pfn, PAGE_KERNEL), 0)); 2.30 - } else { 2.31 - struct mmuext_op op; 2.32 - 2.33 - op.cmd = MMUEXT_UNPIN_TABLE; 2.34 - op.arg1.mfn = pfn_to_mfn(pfn); 2.35 - BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); 2.36 - } 2.37 + } else 2.38 + clear_bit(PG_pinned, &pte->flags); 2.39 2.40 ClearPageForeign(pte); 2.41 init_page_count(pte); 2.42 @@ -587,46 +573,48 @@ void make_pages_writable(void *va, unsig 2.43 } 2.44 } 2.45 2.46 -static inline void pgd_walk_set_prot(void *pt, pgprot_t flags) 2.47 +static inline int pgd_walk_set_prot(struct page *page, pgprot_t flags) 2.48 { 2.49 - struct page *page = virt_to_page(pt); 2.50 unsigned long pfn = page_to_pfn(page); 2.51 2.52 if (PageHighMem(page)) 2.53 - return; 2.54 + return pgprot_val(flags) & _PAGE_RW 2.55 + ? test_and_clear_bit(PG_pinned, &page->flags) 2.56 + : !test_and_set_bit(PG_pinned, &page->flags); 2.57 + 2.58 BUG_ON(HYPERVISOR_update_va_mapping( 2.59 (unsigned long)__va(pfn << PAGE_SHIFT), 2.60 pfn_pte(pfn, flags), 0)); 2.61 + 2.62 + return 0; 2.63 } 2.64 2.65 -static void pgd_walk(pgd_t *pgd_base, pgprot_t flags) 2.66 +static int pgd_walk(pgd_t *pgd_base, pgprot_t flags) 2.67 { 2.68 pgd_t *pgd = pgd_base; 2.69 pud_t *pud; 2.70 pmd_t *pmd; 2.71 - pte_t *pte; 2.72 - int g, u, m; 2.73 + int g, u, m, flush; 2.74 2.75 if (xen_feature(XENFEAT_auto_translated_physmap)) 2.76 - return; 2.77 + return 0; 2.78 2.79 - for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) { 2.80 + for (g = 0, flush = 0; g < USER_PTRS_PER_PGD; g++, pgd++) { 2.81 if (pgd_none(*pgd)) 2.82 continue; 2.83 pud = pud_offset(pgd, 0); 2.84 if (PTRS_PER_PUD > 1) /* not folded */ 2.85 - pgd_walk_set_prot(pud,flags); 2.86 + flush |= pgd_walk_set_prot(virt_to_page(pud),flags); 2.87 for (u = 0; u < PTRS_PER_PUD; u++, pud++) { 2.88 if (pud_none(*pud)) 2.89 continue; 2.90 pmd = pmd_offset(pud, 0); 2.91 if (PTRS_PER_PMD > 1) /* not folded */ 2.92 - pgd_walk_set_prot(pmd,flags); 2.93 + flush |= pgd_walk_set_prot(virt_to_page(pmd),flags); 2.94 for (m = 0; m < PTRS_PER_PMD; m++, pmd++) { 2.95 if (pmd_none(*pmd)) 2.96 continue; 2.97 - pte = pte_offset_kernel(pmd,0); 2.98 - pgd_walk_set_prot(pte,flags); 2.99 + flush |= pgd_walk_set_prot(pmd_page(*pmd),flags); 2.100 } 2.101 } 2.102 } 2.103 @@ -635,11 +623,14 @@ static void pgd_walk(pgd_t *pgd_base, pg 2.104 (unsigned long)pgd_base, 2.105 pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags), 2.106 UVMF_TLB_FLUSH)); 2.107 + 2.108 + return flush; 2.109 } 2.110 2.111 static void __pgd_pin(pgd_t *pgd) 2.112 { 2.113 - pgd_walk(pgd, PAGE_KERNEL_RO); 2.114 + if (pgd_walk(pgd, PAGE_KERNEL_RO)) 2.115 + kmap_flush_unused(); 2.116 xen_pgd_pin(__pa(pgd)); 2.117 set_bit(PG_pinned, &virt_to_page(pgd)->flags); 2.118 } 2.119 @@ -647,7 +638,8 @@ static void __pgd_pin(pgd_t *pgd) 2.120 static void __pgd_unpin(pgd_t *pgd) 2.121 { 2.122 xen_pgd_unpin(__pa(pgd)); 2.123 - pgd_walk(pgd, PAGE_KERNEL); 2.124 + if (pgd_walk(pgd, PAGE_KERNEL)) 2.125 + kmap_flush_unused(); 2.126 clear_bit(PG_pinned, &virt_to_page(pgd)->flags); 2.127 } 2.128
3.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon Jan 22 15:31:27 2007 +0000 3.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon Jan 22 15:42:13 2007 +0000 3.3 @@ -28,13 +28,12 @@ 3.4 #include <asm/bug.h> 3.5 #include <xen/interface/xen.h> 3.6 #include <xen/features.h> 3.7 -#include <xen/foreign_page.h> 3.8 3.9 -#define arch_free_page(_page,_order) \ 3.10 -({ int foreign = PageForeign(_page); \ 3.11 - if (foreign) \ 3.12 - (PageForeignDestructor(_page))(_page); \ 3.13 - foreign; \ 3.14 +#define arch_free_page(_page,_order) \ 3.15 +({ int foreign = PageForeign(_page); \ 3.16 + if (foreign) \ 3.17 + PageForeignDestructor(_page); \ 3.18 + foreign; \ 3.19 }) 3.20 #define HAVE_ARCH_FREE_PAGE 3.21
4.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h Mon Jan 22 15:31:27 2007 +0000 4.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h Mon Jan 22 15:42:13 2007 +0000 4.3 @@ -6,27 +6,23 @@ 4.4 #include <linux/mm.h> /* for struct page */ 4.5 #include <asm/io.h> /* for phys_to_virt and page_to_pseudophys */ 4.6 4.7 -/* Is this pagetable pinned? */ 4.8 -#define PG_pinned PG_arch_1 4.9 - 4.10 #define pmd_populate_kernel(mm, pmd, pte) \ 4.11 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) 4.12 4.13 #define pmd_populate(mm, pmd, pte) \ 4.14 do { \ 4.15 + unsigned long pfn = page_to_pfn(pte); \ 4.16 if (test_bit(PG_pinned, &virt_to_page((mm)->pgd)->flags)) { \ 4.17 if (!PageHighMem(pte)) \ 4.18 BUG_ON(HYPERVISOR_update_va_mapping( \ 4.19 - (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT),\ 4.20 - pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));\ 4.21 - set_pmd(pmd, __pmd(_PAGE_TABLE + \ 4.22 - ((unsigned long long)page_to_pfn(pte) << \ 4.23 - (unsigned long long) PAGE_SHIFT))); \ 4.24 - } else { \ 4.25 - *(pmd) = __pmd(_PAGE_TABLE + \ 4.26 - ((unsigned long long)page_to_pfn(pte) << \ 4.27 - (unsigned long long) PAGE_SHIFT)); \ 4.28 - } \ 4.29 + (unsigned long)__va(pfn << PAGE_SHIFT), \ 4.30 + pfn_pte(pfn, PAGE_KERNEL_RO), 0)); \ 4.31 + else if (!test_and_set_bit(PG_pinned, &pte->flags)) \ 4.32 + kmap_flush_unused(); \ 4.33 + set_pmd(pmd, \ 4.34 + __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT))); \ 4.35 + } else \ 4.36 + *(pmd) = __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT)); \ 4.37 } while (0) 4.38 4.39 /*
5.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h Mon Jan 22 15:31:27 2007 +0000 5.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h Mon Jan 22 15:42:13 2007 +0000 5.3 @@ -25,6 +25,9 @@ 5.4 #include <linux/list.h> 5.5 #include <linux/spinlock.h> 5.6 5.7 +/* Is this pagetable pinned? */ 5.8 +#define PG_pinned PG_arch_1 5.9 + 5.10 struct mm_struct; 5.11 struct vm_area_struct; 5.12
6.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Mon Jan 22 15:31:27 2007 +0000 6.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Mon Jan 22 15:42:13 2007 +0000 6.3 @@ -8,13 +8,12 @@ 6.4 #include <asm/bug.h> 6.5 #endif 6.6 #include <xen/interface/xen.h> 6.7 -#include <xen/foreign_page.h> 6.8 6.9 -#define arch_free_page(_page,_order) \ 6.10 -({ int foreign = PageForeign(_page); \ 6.11 - if (foreign) \ 6.12 - (PageForeignDestructor(_page))(_page); \ 6.13 - foreign; \ 6.14 +#define arch_free_page(_page,_order) \ 6.15 +({ int foreign = PageForeign(_page); \ 6.16 + if (foreign) \ 6.17 + PageForeignDestructor(_page); \ 6.18 + foreign; \ 6.19 }) 6.20 #define HAVE_ARCH_FREE_PAGE 6.21
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/linux-2.6-xen-sparse/include/linux/page-flags.h Mon Jan 22 15:42:13 2007 +0000 7.3 @@ -0,0 +1,280 @@ 7.4 +/* 7.5 + * Macros for manipulating and testing page->flags 7.6 + */ 7.7 + 7.8 +#ifndef PAGE_FLAGS_H 7.9 +#define PAGE_FLAGS_H 7.10 + 7.11 +#include <linux/types.h> 7.12 + 7.13 +/* 7.14 + * Various page->flags bits: 7.15 + * 7.16 + * PG_reserved is set for special pages, which can never be swapped out. Some 7.17 + * of them might not even exist (eg empty_bad_page)... 7.18 + * 7.19 + * The PG_private bitflag is set if page->private contains a valid value. 7.20 + * 7.21 + * During disk I/O, PG_locked is used. This bit is set before I/O and 7.22 + * reset when I/O completes. page_waitqueue(page) is a wait queue of all tasks 7.23 + * waiting for the I/O on this page to complete. 7.24 + * 7.25 + * PG_uptodate tells whether the page's contents is valid. When a read 7.26 + * completes, the page becomes uptodate, unless a disk I/O error happened. 7.27 + * 7.28 + * For choosing which pages to swap out, inode pages carry a PG_referenced bit, 7.29 + * which is set any time the system accesses that page through the (mapping, 7.30 + * index) hash table. This referenced bit, together with the referenced bit 7.31 + * in the page tables, is used to manipulate page->age and move the page across 7.32 + * the active, inactive_dirty and inactive_clean lists. 7.33 + * 7.34 + * Note that the referenced bit, the page->lru list_head and the active, 7.35 + * inactive_dirty and inactive_clean lists are protected by the 7.36 + * zone->lru_lock, and *NOT* by the usual PG_locked bit! 7.37 + * 7.38 + * PG_error is set to indicate that an I/O error occurred on this page. 7.39 + * 7.40 + * PG_arch_1 is an architecture specific page state bit. The generic code 7.41 + * guarantees that this bit is cleared for a page when it first is entered into 7.42 + * the page cache. 7.43 + * 7.44 + * PG_highmem pages are not permanently mapped into the kernel virtual address 7.45 + * space, they need to be kmapped separately for doing IO on the pages. The 7.46 + * struct page (these bits with information) are always mapped into kernel 7.47 + * address space... 7.48 + */ 7.49 + 7.50 +/* 7.51 + * Don't use the *_dontuse flags. Use the macros. Otherwise you'll break 7.52 + * locked- and dirty-page accounting. 7.53 + * 7.54 + * The page flags field is split into two parts, the main flags area 7.55 + * which extends from the low bits upwards, and the fields area which 7.56 + * extends from the high bits downwards. 7.57 + * 7.58 + * | FIELD | ... | FLAGS | 7.59 + * N-1 ^ 0 7.60 + * (N-FLAGS_RESERVED) 7.61 + * 7.62 + * The fields area is reserved for fields mapping zone, node and SPARSEMEM 7.63 + * section. The boundry between these two areas is defined by 7.64 + * FLAGS_RESERVED which defines the width of the fields section 7.65 + * (see linux/mmzone.h). New flags must _not_ overlap with this area. 7.66 + */ 7.67 +#define PG_locked 0 /* Page is locked. Don't touch. */ 7.68 +#define PG_error 1 7.69 +#define PG_referenced 2 7.70 +#define PG_uptodate 3 7.71 + 7.72 +#define PG_dirty 4 7.73 +#define PG_lru 5 7.74 +#define PG_active 6 7.75 +#define PG_slab 7 /* slab debug (Suparna wants this) */ 7.76 + 7.77 +#define PG_checked 8 /* kill me in 2.5.<early>. */ 7.78 +#define PG_arch_1 9 7.79 +#define PG_reserved 10 7.80 +#define PG_private 11 /* Has something at ->private */ 7.81 + 7.82 +#define PG_writeback 12 /* Page is under writeback */ 7.83 +#define PG_nosave 13 /* Used for system suspend/resume */ 7.84 +#define PG_compound 14 /* Part of a compound page */ 7.85 +#define PG_swapcache 15 /* Swap page: swp_entry_t in private */ 7.86 + 7.87 +#define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ 7.88 +#define PG_reclaim 17 /* To be reclaimed asap */ 7.89 +#define PG_nosave_free 18 /* Free, should not be written */ 7.90 +#define PG_buddy 19 /* Page is free, on buddy lists */ 7.91 + 7.92 + 7.93 +#if (BITS_PER_LONG > 32) 7.94 +/* 7.95 + * 64-bit-only flags build down from bit 31 7.96 + * 7.97 + * 32 bit -------------------------------| FIELDS | FLAGS | 7.98 + * 64 bit | FIELDS | ?????? FLAGS | 7.99 + * 63 32 0 7.100 + */ 7.101 +#define PG_uncached 31 /* Page has been mapped as uncached */ 7.102 +#endif 7.103 + 7.104 +#define PG_foreign 20 /* Page is owned by foreign allocator. */ 7.105 + 7.106 +/* 7.107 + * Manipulation of page state flags 7.108 + */ 7.109 +#define PageLocked(page) \ 7.110 + test_bit(PG_locked, &(page)->flags) 7.111 +#define SetPageLocked(page) \ 7.112 + set_bit(PG_locked, &(page)->flags) 7.113 +#define TestSetPageLocked(page) \ 7.114 + test_and_set_bit(PG_locked, &(page)->flags) 7.115 +#define ClearPageLocked(page) \ 7.116 + clear_bit(PG_locked, &(page)->flags) 7.117 +#define TestClearPageLocked(page) \ 7.118 + test_and_clear_bit(PG_locked, &(page)->flags) 7.119 + 7.120 +#define PageError(page) test_bit(PG_error, &(page)->flags) 7.121 +#define SetPageError(page) set_bit(PG_error, &(page)->flags) 7.122 +#define ClearPageError(page) clear_bit(PG_error, &(page)->flags) 7.123 + 7.124 +#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags) 7.125 +#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags) 7.126 +#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags) 7.127 +#define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags) 7.128 + 7.129 +#define PageUptodate(page) test_bit(PG_uptodate, &(page)->flags) 7.130 +#ifdef CONFIG_S390 7.131 +#define SetPageUptodate(_page) \ 7.132 + do { \ 7.133 + struct page *__page = (_page); \ 7.134 + if (!test_and_set_bit(PG_uptodate, &__page->flags)) \ 7.135 + page_test_and_clear_dirty(_page); \ 7.136 + } while (0) 7.137 +#else 7.138 +#define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags) 7.139 +#endif 7.140 +#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags) 7.141 + 7.142 +#define PageDirty(page) test_bit(PG_dirty, &(page)->flags) 7.143 +#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags) 7.144 +#define TestSetPageDirty(page) test_and_set_bit(PG_dirty, &(page)->flags) 7.145 +#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags) 7.146 +#define __ClearPageDirty(page) __clear_bit(PG_dirty, &(page)->flags) 7.147 +#define TestClearPageDirty(page) test_and_clear_bit(PG_dirty, &(page)->flags) 7.148 + 7.149 +#define PageLRU(page) test_bit(PG_lru, &(page)->flags) 7.150 +#define SetPageLRU(page) set_bit(PG_lru, &(page)->flags) 7.151 +#define ClearPageLRU(page) clear_bit(PG_lru, &(page)->flags) 7.152 +#define __ClearPageLRU(page) __clear_bit(PG_lru, &(page)->flags) 7.153 + 7.154 +#define PageActive(page) test_bit(PG_active, &(page)->flags) 7.155 +#define SetPageActive(page) set_bit(PG_active, &(page)->flags) 7.156 +#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags) 7.157 +#define __ClearPageActive(page) __clear_bit(PG_active, &(page)->flags) 7.158 + 7.159 +#define PageSlab(page) test_bit(PG_slab, &(page)->flags) 7.160 +#define __SetPageSlab(page) __set_bit(PG_slab, &(page)->flags) 7.161 +#define __ClearPageSlab(page) __clear_bit(PG_slab, &(page)->flags) 7.162 + 7.163 +#ifdef CONFIG_HIGHMEM 7.164 +#define PageHighMem(page) is_highmem(page_zone(page)) 7.165 +#else 7.166 +#define PageHighMem(page) 0 /* needed to optimize away at compile time */ 7.167 +#endif 7.168 + 7.169 +#define PageChecked(page) test_bit(PG_checked, &(page)->flags) 7.170 +#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags) 7.171 +#define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags) 7.172 + 7.173 +#define PageReserved(page) test_bit(PG_reserved, &(page)->flags) 7.174 +#define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags) 7.175 +#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags) 7.176 +#define __ClearPageReserved(page) __clear_bit(PG_reserved, &(page)->flags) 7.177 + 7.178 +#define SetPagePrivate(page) set_bit(PG_private, &(page)->flags) 7.179 +#define ClearPagePrivate(page) clear_bit(PG_private, &(page)->flags) 7.180 +#define PagePrivate(page) test_bit(PG_private, &(page)->flags) 7.181 +#define __SetPagePrivate(page) __set_bit(PG_private, &(page)->flags) 7.182 +#define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags) 7.183 + 7.184 +#define PageWriteback(page) test_bit(PG_writeback, &(page)->flags) 7.185 +#define SetPageWriteback(page) \ 7.186 + do { \ 7.187 + if (!test_and_set_bit(PG_writeback, \ 7.188 + &(page)->flags)) \ 7.189 + inc_zone_page_state(page, NR_WRITEBACK); \ 7.190 + } while (0) 7.191 +#define TestSetPageWriteback(page) \ 7.192 + ({ \ 7.193 + int ret; \ 7.194 + ret = test_and_set_bit(PG_writeback, \ 7.195 + &(page)->flags); \ 7.196 + if (!ret) \ 7.197 + inc_zone_page_state(page, NR_WRITEBACK); \ 7.198 + ret; \ 7.199 + }) 7.200 +#define ClearPageWriteback(page) \ 7.201 + do { \ 7.202 + if (test_and_clear_bit(PG_writeback, \ 7.203 + &(page)->flags)) \ 7.204 + dec_zone_page_state(page, NR_WRITEBACK); \ 7.205 + } while (0) 7.206 +#define TestClearPageWriteback(page) \ 7.207 + ({ \ 7.208 + int ret; \ 7.209 + ret = test_and_clear_bit(PG_writeback, \ 7.210 + &(page)->flags); \ 7.211 + if (ret) \ 7.212 + dec_zone_page_state(page, NR_WRITEBACK); \ 7.213 + ret; \ 7.214 + }) 7.215 + 7.216 +#define PageNosave(page) test_bit(PG_nosave, &(page)->flags) 7.217 +#define SetPageNosave(page) set_bit(PG_nosave, &(page)->flags) 7.218 +#define TestSetPageNosave(page) test_and_set_bit(PG_nosave, &(page)->flags) 7.219 +#define ClearPageNosave(page) clear_bit(PG_nosave, &(page)->flags) 7.220 +#define TestClearPageNosave(page) test_and_clear_bit(PG_nosave, &(page)->flags) 7.221 + 7.222 +#define PageNosaveFree(page) test_bit(PG_nosave_free, &(page)->flags) 7.223 +#define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags) 7.224 +#define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags) 7.225 + 7.226 +#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags) 7.227 +#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags) 7.228 +#define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags) 7.229 + 7.230 +#define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) 7.231 +#define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) 7.232 +#define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) 7.233 + 7.234 +#define PageReclaim(page) test_bit(PG_reclaim, &(page)->flags) 7.235 +#define SetPageReclaim(page) set_bit(PG_reclaim, &(page)->flags) 7.236 +#define ClearPageReclaim(page) clear_bit(PG_reclaim, &(page)->flags) 7.237 +#define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags) 7.238 + 7.239 +#define PageCompound(page) test_bit(PG_compound, &(page)->flags) 7.240 +#define __SetPageCompound(page) __set_bit(PG_compound, &(page)->flags) 7.241 +#define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags) 7.242 + 7.243 +#ifdef CONFIG_SWAP 7.244 +#define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags) 7.245 +#define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags) 7.246 +#define ClearPageSwapCache(page) clear_bit(PG_swapcache, &(page)->flags) 7.247 +#else 7.248 +#define PageSwapCache(page) 0 7.249 +#endif 7.250 + 7.251 +#define PageUncached(page) test_bit(PG_uncached, &(page)->flags) 7.252 +#define SetPageUncached(page) set_bit(PG_uncached, &(page)->flags) 7.253 +#define ClearPageUncached(page) clear_bit(PG_uncached, &(page)->flags) 7.254 + 7.255 +#define PageForeign(page) test_bit(PG_foreign, &(page)->flags) 7.256 +#define SetPageForeign(page, dtor) do { \ 7.257 + set_bit(PG_foreign, &(page)->flags); \ 7.258 + (page)->mapping = (void *)dtor; \ 7.259 +} while (0) 7.260 +#define ClearPageForeign(page) do { \ 7.261 + clear_bit(PG_foreign, &(page)->flags); \ 7.262 + (page)->mapping = NULL; \ 7.263 +} while (0) 7.264 +#define PageForeignDestructor(page) \ 7.265 + ( (void (*) (struct page *)) (page)->mapping )(page) 7.266 + 7.267 +struct page; /* forward declaration */ 7.268 + 7.269 +int test_clear_page_dirty(struct page *page); 7.270 +int test_clear_page_writeback(struct page *page); 7.271 +int test_set_page_writeback(struct page *page); 7.272 + 7.273 +static inline void clear_page_dirty(struct page *page) 7.274 +{ 7.275 + test_clear_page_dirty(page); 7.276 +} 7.277 + 7.278 +static inline void set_page_writeback(struct page *page) 7.279 +{ 7.280 + test_set_page_writeback(page); 7.281 +} 7.282 + 7.283 +#endif /* PAGE_FLAGS_H */
8.1 --- a/linux-2.6-xen-sparse/include/xen/foreign_page.h Mon Jan 22 15:31:27 2007 +0000 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,30 +0,0 @@ 8.4 -/****************************************************************************** 8.5 - * foreign_page.h 8.6 - * 8.7 - * Provide a "foreign" page type, that is owned by a foreign allocator and 8.8 - * not the normal buddy allocator in page_alloc.c 8.9 - * 8.10 - * Copyright (c) 2004, K A Fraser 8.11 - */ 8.12 - 8.13 -#ifndef __ASM_XEN_FOREIGN_PAGE_H__ 8.14 -#define __ASM_XEN_FOREIGN_PAGE_H__ 8.15 - 8.16 -#define PG_foreign PG_arch_1 8.17 - 8.18 -#define PageForeign(page) test_bit(PG_foreign, &(page)->flags) 8.19 - 8.20 -#define SetPageForeign(page, dtor) do { \ 8.21 - set_bit(PG_foreign, &(page)->flags); \ 8.22 - (page)->mapping = (void *)dtor; \ 8.23 -} while (0) 8.24 - 8.25 -#define ClearPageForeign(page) do { \ 8.26 - clear_bit(PG_foreign, &(page)->flags); \ 8.27 - (page)->mapping = NULL; \ 8.28 -} while (0) 8.29 - 8.30 -#define PageForeignDestructor(page) \ 8.31 - ( (void (*) (struct page *)) (page)->mapping ) 8.32 - 8.33 -#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
9.1 --- a/linux-2.6-xen-sparse/mm/page_alloc.c Mon Jan 22 15:31:27 2007 +0000 9.2 +++ b/linux-2.6-xen-sparse/mm/page_alloc.c Mon Jan 22 15:42:13 2007 +0000 9.3 @@ -154,7 +154,11 @@ static void bad_page(struct page *page) 9.4 1 << PG_slab | 9.5 1 << PG_swapcache | 9.6 1 << PG_writeback | 9.7 - 1 << PG_buddy ); 9.8 + 1 << PG_buddy | 9.9 +#ifdef CONFIG_X86_XEN 9.10 + 1 << PG_pinned | 9.11 +#endif 9.12 + 1 << PG_foreign ); 9.13 set_page_count(page, 0); 9.14 reset_page_mapcount(page); 9.15 page->mapping = NULL; 9.16 @@ -389,7 +393,11 @@ static inline int free_pages_check(struc 9.17 1 << PG_swapcache | 9.18 1 << PG_writeback | 9.19 1 << PG_reserved | 9.20 - 1 << PG_buddy )))) 9.21 + 1 << PG_buddy | 9.22 +#ifdef CONFIG_X86_XEN 9.23 + 1 << PG_pinned | 9.24 +#endif 9.25 + 1 << PG_foreign )))) 9.26 bad_page(page); 9.27 if (PageDirty(page)) 9.28 __ClearPageDirty(page); 9.29 @@ -539,7 +547,11 @@ static int prep_new_page(struct page *pa 9.30 1 << PG_swapcache | 9.31 1 << PG_writeback | 9.32 1 << PG_reserved | 9.33 - 1 << PG_buddy )))) 9.34 + 1 << PG_buddy | 9.35 +#ifdef CONFIG_X86_XEN 9.36 + 1 << PG_pinned | 9.37 +#endif 9.38 + 1 << PG_foreign )))) 9.39 bad_page(page); 9.40 9.41 /*