aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2006-03-22 03:08:33 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 10:54:01 -0500
commit4fa4f53bf92139595cae6f1a3d972fc0a3451d29 (patch)
treea564a675bed7f34b1a05fce4055ea97e509ecf62 /arch/x86_64
parent20aaffd6a6492a5f7975dd7be967cdf0e4d978c4 (diff)
[PATCH] x86_64: pageattr remove __put_page
Remove page_count and __put_page from x86-64 pageattr Signed-off-by: Nick Piggin <npiggin@suse.de> Acked-by: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/mm/pageattr.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index efe5af14c7db..531ad21447b1 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -45,6 +45,13 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
45 pte_t *pbase; 45 pte_t *pbase;
46 if (!base) 46 if (!base)
47 return NULL; 47 return NULL;
48 /*
49 * page_private is used to track the number of entries in
50 * the page table page have non standard attributes.
51 */
52 SetPagePrivate(base);
53 page_private(base) = 0;
54
48 address = __pa(address); 55 address = __pa(address);
49 addr = address & LARGE_PAGE_MASK; 56 addr = address & LARGE_PAGE_MASK;
50 pbase = (pte_t *)page_address(base); 57 pbase = (pte_t *)page_address(base);
@@ -124,8 +131,8 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
124 set_pte(kpte, pfn_pte(pfn, prot)); 131 set_pte(kpte, pfn_pte(pfn, prot));
125 } else { 132 } else {
126 /* 133 /*
127 * split_large_page will take the reference for this change_page_attr 134 * split_large_page will take the reference for this
128 * on the split page. 135 * change_page_attr on the split page.
129 */ 136 */
130 137
131 struct page *split; 138 struct page *split;
@@ -137,23 +144,20 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
137 set_pte(kpte,mk_pte(split, ref_prot2)); 144 set_pte(kpte,mk_pte(split, ref_prot2));
138 kpte_page = split; 145 kpte_page = split;
139 } 146 }
140 get_page(kpte_page); 147 page_private(kpte_page)++;
141 } else if ((kpte_flags & _PAGE_PSE) == 0) { 148 } else if ((kpte_flags & _PAGE_PSE) == 0) {
142 set_pte(kpte, pfn_pte(pfn, ref_prot)); 149 set_pte(kpte, pfn_pte(pfn, ref_prot));
143 __put_page(kpte_page); 150 BUG_ON(page_private(kpte_page) == 0);
151 page_private(kpte_page)--;
144 } else 152 } else
145 BUG(); 153 BUG();
146 154
147 /* on x86-64 the direct mapping set at boot is not using 4k pages */ 155 /* on x86-64 the direct mapping set at boot is not using 4k pages */
148 BUG_ON(PageReserved(kpte_page)); 156 BUG_ON(PageReserved(kpte_page));
149 157
150 switch (page_count(kpte_page)) { 158 if (page_private(kpte_page) == 0) {
151 case 1:
152 save_page(kpte_page); 159 save_page(kpte_page);
153 revert_page(address, ref_prot); 160 revert_page(address, ref_prot);
154 break;
155 case 0:
156 BUG(); /* memleak and failed 2M page regeneration */
157 } 161 }
158 return 0; 162 return 0;
159} 163}
@@ -216,6 +220,7 @@ void global_flush_tlb(void)
216 while (dpage) { 220 while (dpage) {
217 struct page *tmp = dpage; 221 struct page *tmp = dpage;
218 dpage = (struct page *)dpage->lru.next; 222 dpage = (struct page *)dpage->lru.next;
223 ClearPagePrivate(tmp);
219 __free_page(tmp); 224 __free_page(tmp);
220 } 225 }
221} 226}