diff options
author | Nick Piggin <npiggin@suse.de> | 2006-03-22 03:08:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-22 10:54:01 -0500 |
commit | 4fa4f53bf92139595cae6f1a3d972fc0a3451d29 (patch) | |
tree | a564a675bed7f34b1a05fce4055ea97e509ecf62 /arch/x86_64/mm | |
parent | 20aaffd6a6492a5f7975dd7be967cdf0e4d978c4 (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/mm')
-rw-r--r-- | arch/x86_64/mm/pageattr.c | 23 |
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 | } |