[PATCH] avoid allocating pte_chains for unshared pages
[opensuse:kernel.git] / mm / rmap.c
1 /*
2  * mm/rmap.c - physical to virtual reverse mappings
3  *
4  * Copyright 2001, Rik van Riel <riel@conectiva.com.br>
5  * Released under the General Public License (GPL).
6  *
7  *
8  * Simple, low overhead pte-based reverse mapping scheme.
9  * This is kept modular because we may want to experiment
10  * with object-based reverse mapping schemes. Please try
11  * to keep this thing as modular as possible.
12  */
13
14 /*
15  * Locking:
16  * - the page->pte.chain is protected by the PG_chainlock bit,
17  *   which nests within the pagemap_lru_lock, then the
18  *   mm->page_table_lock, and then the page lock.
19  * - because swapout locking is opposite to the locking order
20  *   in the page fault path, the swapout path uses trylocks
21  *   on the mm->page_table_lock
22  */
23 #include <linux/mm.h>
24 #include <linux/pagemap.h>
25 #include <linux/swapops.h>
26
27 #include <asm/pgalloc.h>
28 #include <asm/rmap.h>
29 #include <asm/smplock.h>
30 #include <asm/tlb.h>
31 #include <asm/tlbflush.h>
32
33 /* #define DEBUG_RMAP */
34
35 /*
36  * Shared pages have a chain of pte_chain structures, used to locate
37  * all the mappings to this page. We only need a pointer to the pte
38  * here, the page struct for the page table page contains the process
39  * it belongs to and the offset within that process.
40  *
41  * A singly linked list should be fine for most, if not all, workloads.
42  * On fork-after-exec the mapping we'll be removing will still be near
43  * the start of the list, on mixed application systems the short-lived
44  * processes will have their mappings near the start of the list and
45  * in systems with long-lived applications the relative overhead of
46  * exit() will be lower since the applications are long-lived.
47  */
48 struct pte_chain {
49         struct pte_chain * next;
50         pte_t * ptep;
51 };
52
53 static inline struct pte_chain * pte_chain_alloc(void);
54 static inline void pte_chain_free(struct pte_chain *, struct pte_chain *,
55                 struct page *);
56 static void alloc_new_pte_chains(void);
57
58 /**
59  * page_referenced - test if the page was referenced
60  * @page: the page to test
61  *
62  * Quick test_and_clear_referenced for all mappings to a page,
63  * returns the number of processes which referenced the page.
64  * Caller needs to hold the pte_chain_lock.
65  */
66 int page_referenced(struct page * page)
67 {
68         struct pte_chain * pc;
69         int referenced = 0;
70
71         if (TestClearPageReferenced(page))
72                 referenced++;
73
74         if (PageDirect(page)) {
75                 if (ptep_test_and_clear_young(page->pte.direct))
76                         referenced++;
77         } else {
78                 /* Check all the page tables mapping this page. */
79                 for (pc = page->pte.chain; pc; pc = pc->next) {
80                         if (ptep_test_and_clear_young(pc->ptep))
81                                 referenced++;
82                 }
83         }
84         return referenced;
85 }
86
87 /**
88  * page_add_rmap - add reverse mapping entry to a page
89  * @page: the page to add the mapping to
90  * @ptep: the page table entry mapping this page
91  *
92  * Add a new pte reverse mapping to a page.
93  * The caller needs to hold the mm->page_table_lock.
94  */
95 void page_add_rmap(struct page * page, pte_t * ptep)
96 {
97         struct pte_chain * pte_chain;
98         unsigned long pfn = pte_pfn(*ptep);
99
100 #ifdef DEBUG_RMAP
101         if (!page || !ptep)
102                 BUG();
103         if (!pte_present(*ptep))
104                 BUG();
105         if (!ptep_to_mm(ptep))
106                 BUG();
107 #endif
108
109         if (!pfn_valid(pfn) || PageReserved(page))
110                 return;
111
112 #ifdef DEBUG_RMAP
113         pte_chain_lock(page);
114         {
115                 struct pte_chain * pc;
116                 if (PageDirect(page)) {
117                         if (page->pte.direct == ptep)
118                                 BUG();
119                 } else {
120                         for (pc = page->pte.chain; pc; pc = pc->next) {
121                                 if (pc->ptep == ptep)
122                                         BUG();
123                         }
124                 }
125         }
126         pte_chain_unlock(page);
127 #endif
128
129         pte_chain_lock(page);
130
131         if (PageDirect(page)) {
132                 /* Convert a direct pointer into a pte_chain */
133                 pte_chain = pte_chain_alloc();
134                 pte_chain->ptep = page->pte.direct;
135                 pte_chain->next = NULL;
136                 page->pte.chain = pte_chain;
137                 ClearPageDirect(page);
138         }
139         if (page->pte.chain) {
140                 /* Hook up the pte_chain to the page. */
141                 pte_chain = pte_chain_alloc();
142                 pte_chain->ptep = ptep;
143                 pte_chain->next = page->pte.chain;
144                 page->pte.chain = pte_chain;
145         } else {
146                 page->pte.direct = ptep;
147                 SetPageDirect(page);
148         }
149
150         pte_chain_unlock(page);
151 }
152
153 /**
154  * page_remove_rmap - take down reverse mapping to a page
155  * @page: page to remove mapping from
156  * @ptep: page table entry to remove
157  *
158  * Removes the reverse mapping from the pte_chain of the page,
159  * after that the caller can clear the page table entry and free
160  * the page.
161  * Caller needs to hold the mm->page_table_lock.
162  */
163 void page_remove_rmap(struct page * page, pte_t * ptep)
164 {
165         struct pte_chain * pc, * prev_pc = NULL;
166         unsigned long pfn = pte_pfn(*ptep);
167
168         if (!page || !ptep)
169                 BUG();
170         if (!pfn_valid(pfn) || PageReserved(page))
171                 return;
172
173         pte_chain_lock(page);
174
175         if (PageDirect(page)) {
176                 if (page->pte.direct == ptep) {
177                         page->pte.direct = NULL;
178                         ClearPageDirect(page);
179                         goto out;
180                 }
181         } else {
182                 for (pc = page->pte.chain; pc; prev_pc = pc, pc = pc->next) {
183                         if (pc->ptep == ptep) {
184                                 pte_chain_free(pc, prev_pc, page);
185                                 /* Check whether we can convert to direct */
186                                 pc = page->pte.chain;
187                                 if (!pc->next) {
188                                         page->pte.direct = pc->ptep;
189                                         SetPageDirect(page);
190                                         pte_chain_free(pc, NULL, NULL);
191                                 }
192                                 goto out;
193                         }
194                 }
195         }
196 #ifdef DEBUG_RMAP
197         /* Not found. This should NEVER happen! */
198         printk(KERN_ERR "page_remove_rmap: pte_chain %p not present.\n", ptep);
199         printk(KERN_ERR "page_remove_rmap: only found: ");
200         if (PageDirect(page)) {
201                 printk("%p ", page->pte.direct);
202         } else {
203                 for (pc = page->pte.chain; pc; pc = pc->next)
204                         printk("%p ", pc->ptep);
205         }
206         printk("\n");
207         printk(KERN_ERR "page_remove_rmap: driver cleared PG_reserved ?\n");
208 #endif
209
210 out:
211         pte_chain_unlock(page);
212         return;
213                         
214 }
215
216 /**
217  * try_to_unmap_one - worker function for try_to_unmap
218  * @page: page to unmap
219  * @ptep: page table entry to unmap from page
220  *
221  * Internal helper function for try_to_unmap, called for each page
222  * table entry mapping a page. Because locking order here is opposite
223  * to the locking order used by the page fault path, we use trylocks.
224  * Locking:
225  *      pagemap_lru_lock                page_launder()
226  *          page lock                   page_launder(), trylock
227  *              pte_chain_lock          page_launder()
228  *                  mm->page_table_lock try_to_unmap_one(), trylock
229  */
230 static int FASTCALL(try_to_unmap_one(struct page *, pte_t *));
231 static int try_to_unmap_one(struct page * page, pte_t * ptep)
232 {
233         unsigned long address = ptep_to_address(ptep);
234         struct mm_struct * mm = ptep_to_mm(ptep);
235         struct vm_area_struct * vma;
236         pte_t pte;
237         int ret;
238
239         if (!mm)
240                 BUG();
241
242         /*
243          * We need the page_table_lock to protect us from page faults,
244          * munmap, fork, etc...
245          */
246         if (!spin_trylock(&mm->page_table_lock))
247                 return SWAP_AGAIN;
248
249         /* During mremap, it's possible pages are not in a VMA. */
250         vma = find_vma(mm, address);
251         if (!vma) {
252                 ret = SWAP_FAIL;
253                 goto out_unlock;
254         }
255
256         /* The page is mlock()d, we cannot swap it out. */
257         if (vma->vm_flags & VM_LOCKED) {
258                 ret = SWAP_FAIL;
259                 goto out_unlock;
260         }
261
262         /* Nuke the page table entry. */
263         pte = ptep_get_and_clear(ptep);
264         flush_tlb_page(vma, address);
265         flush_cache_page(vma, address);
266
267         /* Store the swap location in the pte. See handle_pte_fault() ... */
268         if (PageSwapCache(page)) {
269                 swp_entry_t entry;
270                 entry.val = page->index;
271                 swap_duplicate(entry);
272                 set_pte(ptep, swp_entry_to_pte(entry));
273         }
274
275         /* Move the dirty bit to the physical page now the pte is gone. */
276         if (pte_dirty(pte))
277                 set_page_dirty(page);
278
279         mm->rss--;
280         page_cache_release(page);
281         ret = SWAP_SUCCESS;
282
283 out_unlock:
284         spin_unlock(&mm->page_table_lock);
285         return ret;
286 }
287
288 /**
289  * try_to_unmap - try to remove all page table mappings to a page
290  * @page: the page to get unmapped
291  *
292  * Tries to remove all the page table entries which are mapping this
293  * page, used in the pageout path.  Caller must hold pagemap_lru_lock
294  * and the page lock.  Return values are:
295  *
296  * SWAP_SUCCESS - we succeeded in removing all mappings
297  * SWAP_AGAIN   - we missed a trylock, try again later
298  * SWAP_FAIL    - the page is unswappable
299  * SWAP_ERROR   - an error occurred
300  */
301 int try_to_unmap(struct page * page)
302 {
303         struct pte_chain * pc, * next_pc, * prev_pc = NULL;
304         int ret = SWAP_SUCCESS;
305
306         /* This page should not be on the pageout lists. */
307         if (PageReserved(page))
308                 BUG();
309         if (!PageLocked(page))
310                 BUG();
311         /* We need backing store to swap out a page. */
312         if (!page->mapping)
313                 BUG();
314
315         if (PageDirect(page)) {
316                 ret = try_to_unmap_one(page, page->pte.direct);
317                 if (ret == SWAP_SUCCESS) {
318                         page->pte.direct = NULL;
319                         ClearPageDirect(page);
320                 }
321         } else {                
322                 for (pc = page->pte.chain; pc; pc = next_pc) {
323                         next_pc = pc->next;
324                         switch (try_to_unmap_one(page, pc->ptep)) {
325                                 case SWAP_SUCCESS:
326                                         /* Free the pte_chain struct. */
327                                         pte_chain_free(pc, prev_pc, page);
328                                         break;
329                                 case SWAP_AGAIN:
330                                         /* Skip this pte, remembering status. */
331                                         prev_pc = pc;
332                                         ret = SWAP_AGAIN;
333                                         continue;
334                                 case SWAP_FAIL:
335                                         ret = SWAP_FAIL;
336                                         break;
337                                 case SWAP_ERROR:
338                                         ret = SWAP_ERROR;
339                                         break;
340                         }
341                 }
342                 /* Check whether we can convert to direct pte pointer */
343                 pc = page->pte.chain;
344                 if (pc && !pc->next) {
345                         page->pte.direct = pc->ptep;
346                         SetPageDirect(page);
347                         pte_chain_free(pc, NULL, NULL);
348                 }
349         }
350         return ret;
351 }
352
353 /**
354  ** No more VM stuff below this comment, only pte_chain helper
355  ** functions.
356  **/
357
358 struct pte_chain * pte_chain_freelist;
359 spinlock_t pte_chain_freelist_lock = SPIN_LOCK_UNLOCKED;
360
361 /* Maybe we should have standard ops for singly linked lists ... - Rik */
362 static inline void pte_chain_push(struct pte_chain * pte_chain)
363 {
364         pte_chain->ptep = NULL;
365         pte_chain->next = pte_chain_freelist;
366         pte_chain_freelist = pte_chain;
367 }
368
369 static inline struct pte_chain * pte_chain_pop(void)
370 {
371         struct pte_chain *pte_chain;
372
373         pte_chain = pte_chain_freelist;
374         pte_chain_freelist = pte_chain->next;
375         pte_chain->next = NULL;
376
377         return pte_chain;
378 }
379
380 /**
381  * pte_chain_free - free pte_chain structure
382  * @pte_chain: pte_chain struct to free
383  * @prev_pte_chain: previous pte_chain on the list (may be NULL)
384  * @page: page this pte_chain hangs off (may be NULL)
385  *
386  * This function unlinks pte_chain from the singly linked list it
387  * may be on and adds the pte_chain to the free list. May also be
388  * called for new pte_chain structures which aren't on any list yet.
389  * Caller needs to hold the pte_chain_lock if the page is non-NULL.
390  */
391 static inline void pte_chain_free(struct pte_chain * pte_chain,
392                 struct pte_chain * prev_pte_chain, struct page * page)
393 {
394         if (prev_pte_chain)
395                 prev_pte_chain->next = pte_chain->next;
396         else if (page)
397                 page->pte.chain = pte_chain->next;
398
399         spin_lock(&pte_chain_freelist_lock);
400         pte_chain_push(pte_chain);
401         spin_unlock(&pte_chain_freelist_lock);
402 }
403
404 /**
405  * pte_chain_alloc - allocate a pte_chain struct
406  *
407  * Returns a pointer to a fresh pte_chain structure. Allocates new
408  * pte_chain structures as required.
409  * Caller needs to hold the page's pte_chain_lock.
410  */
411 static inline struct pte_chain * pte_chain_alloc()
412 {
413         struct pte_chain * pte_chain;
414
415         spin_lock(&pte_chain_freelist_lock);
416
417         /* Allocate new pte_chain structs as needed. */
418         if (!pte_chain_freelist)
419                 alloc_new_pte_chains();
420
421         /* Grab the first pte_chain from the freelist. */
422         pte_chain = pte_chain_pop();
423
424         spin_unlock(&pte_chain_freelist_lock);
425
426         return pte_chain;
427 }
428
429 /**
430  * alloc_new_pte_chains - convert a free page to pte_chain structures
431  *
432  * Grabs a free page and converts it to pte_chain structures. We really
433  * should pre-allocate these earlier in the pagefault path or come up
434  * with some other trick.
435  *
436  * Note that we cannot use the slab cache because the pte_chain structure
437  * is way smaller than the minimum size of a slab cache allocation.
438  * Caller needs to hold the pte_chain_freelist_lock
439  */
440 static void alloc_new_pte_chains()
441 {
442         struct pte_chain * pte_chain = (void *) get_zeroed_page(GFP_ATOMIC);
443         int i = PAGE_SIZE / sizeof(struct pte_chain);
444
445         if (pte_chain) {
446                 for (; i-- > 0; pte_chain++)
447                         pte_chain_push(pte_chain);
448         } else {
449                 /* Yeah yeah, I'll fix the pte_chain allocation ... */
450                 panic("Fix pte_chain allocation, you lazy bastard!\n");
451         }
452 }