aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2006-03-22 03:08:32 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 10:54:01 -0500
commit20aaffd6a6492a5f7975dd7be967cdf0e4d978c4 (patch)
treeb6202e19d2c42dfcc7bbb6c266034e695adac137 /arch/x86_64
parent84d1c054b1c408c6c92676069fa678d55d5f0033 (diff)
[PATCH] x86_64: pageattr use single list
Use page->lru.next to implement the singly linked list of pages rather than the struct deferred_page which needs to be allocated and freed for each page. 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.c42
1 files changed, 14 insertions, 28 deletions
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 35f1f1aab063..efe5af14c7db 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -77,26 +77,12 @@ static inline void flush_map(unsigned long address)
77 on_each_cpu(flush_kernel_map, (void *)address, 1, 1); 77 on_each_cpu(flush_kernel_map, (void *)address, 1, 1);
78} 78}
79 79
80struct deferred_page { 80static struct page *deferred_pages; /* protected by init_mm.mmap_sem */
81 struct deferred_page *next; 81
82 struct page *fpage; 82static inline void save_page(struct page *fpage)
83 unsigned long address;
84};
85static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
86
87static inline void save_page(unsigned long address, struct page *fpage)
88{ 83{
89 struct deferred_page *df; 84 fpage->lru.next = (struct list_head *)deferred_pages;
90 df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL); 85 deferred_pages = fpage;
91 if (!df) {
92 flush_map(address);
93 __free_page(fpage);
94 } else {
95 df->next = df_list;
96 df->fpage = fpage;
97 df->address = address;
98 df_list = df;
99 }
100} 86}
101 87
102/* 88/*
@@ -163,7 +149,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
163 149
164 switch (page_count(kpte_page)) { 150 switch (page_count(kpte_page)) {
165 case 1: 151 case 1:
166 save_page(address, kpte_page); 152 save_page(kpte_page);
167 revert_page(address, ref_prot); 153 revert_page(address, ref_prot);
168 break; 154 break;
169 case 0: 155 case 0:
@@ -220,17 +206,17 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot)
220 206
221void global_flush_tlb(void) 207void global_flush_tlb(void)
222{ 208{
223 struct deferred_page *df, *next_df; 209 struct page *dpage;
224 210
225 down_read(&init_mm.mmap_sem); 211 down_read(&init_mm.mmap_sem);
226 df = xchg(&df_list, NULL); 212 dpage = xchg(&deferred_pages, NULL);
227 up_read(&init_mm.mmap_sem); 213 up_read(&init_mm.mmap_sem);
228 flush_map((df && !df->next) ? df->address : 0); 214
229 for (; df; df = next_df) { 215 flush_map((dpage && !dpage->lru.next) ? (unsigned long)page_address(dpage) : 0);
230 next_df = df->next; 216 while (dpage) {
231 if (df->fpage) 217 struct page *tmp = dpage;
232 __free_page(df->fpage); 218 dpage = (struct page *)dpage->lru.next;
233 kfree(df); 219 __free_page(tmp);
234 } 220 }
235} 221}
236 222