File: /usr/src/linux/mm/swap_state.c

1     /*
2      *  linux/mm/swap_state.c
3      *
4      *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
5      *  Swap reorganised 29.12.95, Stephen Tweedie
6      *
7      *  Rewritten to use page cache, (C) 1998 Stephen Tweedie
8      */
9     
10     #include <linux/mm.h>
11     #include <linux/kernel_stat.h>
12     #include <linux/swap.h>
13     #include <linux/swapctl.h>
14     #include <linux/init.h>
15     #include <linux/pagemap.h>
16     #include <linux/smp_lock.h>
17     
18     #include <asm/pgtable.h>
19     
20     /*
21      * We may have stale swap cache pages in memory: notice
22      * them here and get rid of the unnecessary final write.
23      */
24     static int swap_writepage(struct page *page)
25     {
26     	if (exclusive_swap_page(page)) {
27     		delete_from_swap_cache(page);
28     		UnlockPage(page);
29     		return 0;
30     	}
31     	rw_swap_page(WRITE, page);
32     	return 0;
33     }
34     
35     static struct address_space_operations swap_aops = {
36     	writepage: swap_writepage,
37     	sync_page: block_sync_page,
38     };
39     
40     struct address_space swapper_space = {
41     	LIST_HEAD_INIT(swapper_space.clean_pages),
42     	LIST_HEAD_INIT(swapper_space.dirty_pages),
43     	LIST_HEAD_INIT(swapper_space.locked_pages),
44     	0,				/* nrpages	*/
45     	&swap_aops,
46     };
47     
48     #ifdef SWAP_CACHE_INFO
49     unsigned long swap_cache_add_total;
50     unsigned long swap_cache_del_total;
51     unsigned long swap_cache_find_total;
52     unsigned long swap_cache_find_success;
53     
54     void show_swap_cache_info(void)
55     {
56     	printk("Swap cache: add %ld, delete %ld, find %ld/%ld\n",
57     		swap_cache_add_total, 
58     		swap_cache_del_total,
59     		swap_cache_find_success, swap_cache_find_total);
60     }
61     #endif
62     
63     void add_to_swap_cache(struct page *page, swp_entry_t entry)
64     {
65     	unsigned long flags;
66     
67     #ifdef SWAP_CACHE_INFO
68     	swap_cache_add_total++;
69     #endif
70     	if (!PageLocked(page))
71     		BUG();
72     	if (page->mapping)
73     		BUG();
74     
75     	/* clear PG_dirty so a subsequent set_page_dirty takes effect */
76     	flags = page->flags & ~(1 << PG_error | 1 << PG_dirty | 1 << PG_arch_1 | 1 << PG_referenced);
77     	page->flags = flags | (1 << PG_uptodate);
78     	add_to_page_cache_locked(page, &swapper_space, entry.val);
79     }
80     
81     /*
82      * This must be called only on pages that have
83      * been verified to be in the swap cache.
84      */
85     void __delete_from_swap_cache(struct page *page)
86     {
87     #ifdef SWAP_CACHE_INFO
88     	swap_cache_del_total++;
89     #endif
90     	if (!PageLocked(page))
91     		BUG();
92     	if (!PageSwapCache(page))
93     		BUG();
94     
95     	ClearPageDirty(page);
96     	__remove_inode_page(page);
97     }
98     
99     /*
100      * This must be called only on pages that have
101      * been verified to be in the swap cache and locked.
102      * It will never put the page into the free list,
103      * the caller has a reference on the page.
104      */
105     void delete_from_swap_cache(struct page *page)
106     {
107     	swp_entry_t entry;
108     
109     	if (!PageLocked(page))
110     		BUG();
111     
112     	if (block_flushpage(page, 0))
113     		lru_cache_del(page);
114     
115     	entry.val = page->index;
116     
117     	spin_lock(&pagecache_lock);
118     	__delete_from_swap_cache(page);
119     	spin_unlock(&pagecache_lock);
120     
121     	swap_free(entry);
122     	page_cache_release(page);
123     }
124     
125     /* 
126      * Perform a free_page(), also freeing any swap cache associated with
127      * this page if it is the last user of the page. Can not do a lock_page,
128      * as we are holding the page_table_lock spinlock.
129      */
130     void free_page_and_swap_cache(struct page *page)
131     {
132     	/* 
133     	 * If we are the only user, then try to free up the swap cache. 
134     	 * 
135     	 * Its ok to check for PageSwapCache without the page lock
136     	 * here because we are going to recheck again inside 
137     	 * exclusive_swap_page() _with_ the lock. 
138     	 * 					- Marcelo
139     	 */
140     	if (PageSwapCache(page) && !TryLockPage(page)) {
141     		if (exclusive_swap_page(page))
142     			delete_from_swap_cache(page);
143     		UnlockPage(page);
144     	}
145     	page_cache_release(page);
146     }
147     
148     /*
149      * Lookup a swap entry in the swap cache. A found page will be returned
150      * unlocked and with its refcount incremented - we rely on the kernel
151      * lock getting page table operations atomic even if we drop the page
152      * lock before returning.
153      */
154     struct page * lookup_swap_cache(swp_entry_t entry)
155     {
156     	struct page *found;
157     
158     #ifdef SWAP_CACHE_INFO
159     	swap_cache_find_total++;
160     #endif
161     	found = find_get_page(&swapper_space, entry.val);
162     	/*
163     	 * Unsafe to assert PageSwapCache and mapping on page found:
164     	 * if SMP nothing prevents swapoff from deleting this page from
165     	 * the swap cache at this moment.  find_lock_page would prevent
166     	 * that, but no need to change: we _have_ got the right page.
167     	 */
168     #ifdef SWAP_CACHE_INFO
169     	if (found)
170     		swap_cache_find_success++;
171     #endif
172     	return found;
173     }
174     
175     /* 
176      * Locate a page of swap in physical memory, reserving swap cache space
177      * and reading the disk if it is not already cached.
178      * A failure return means that either the page allocation failed or that
179      * the swap entry is no longer in use.
180      */
181     struct page * read_swap_cache_async(swp_entry_t entry)
182     {
183     	struct page *found_page, *new_page;
184     	struct page **hash;
185     	
186     	/*
187     	 * Look for the page in the swap cache.  Since we normally call
188     	 * this only after lookup_swap_cache() failed, re-calling that
189     	 * would confuse the statistics: use __find_get_page() directly.
190     	 */
191     	hash = page_hash(&swapper_space, entry.val);
192     	found_page = __find_get_page(&swapper_space, entry.val, hash);
193     	if (found_page)
194     		goto out;
195     
196     	new_page = alloc_page(GFP_HIGHUSER);
197     	if (!new_page)
198     		goto out;		/* Out of memory */
199     	if (TryLockPage(new_page))
200     		BUG();
201     
202     	/*
203     	 * Check the swap cache again, in case we stalled above.
204     	 * swap_list_lock is guarding against races between this check
205     	 * and where the new page is added to the swap cache below.
206     	 * It is also guarding against race where try_to_swap_out
207     	 * allocates entry with get_swap_page then adds to cache.
208     	 */
209     	swap_list_lock();
210     	found_page = __find_get_page(&swapper_space, entry.val, hash);
211     	if (found_page)
212     		goto out_free_page;
213     
214     	/*
215     	 * Make sure the swap entry is still in use.  It could have gone
216     	 * since caller dropped page_table_lock, while allocating page above,
217     	 * or while allocating page in prior call via swapin_readahead.
218     	 */
219     	if (!swap_duplicate(entry))	/* Account for the swap cache */
220     		goto out_free_page;
221     
222     	/* 
223     	 * Add it to the swap cache and read its contents.
224     	 */
225     	add_to_swap_cache(new_page, entry);
226     	swap_list_unlock();
227     
228     	rw_swap_page(READ, new_page);
229     	return new_page;
230     
231     out_free_page:
232     	swap_list_unlock();
233     	UnlockPage(new_page);
234     	page_cache_release(new_page);
235     out:
236     	return found_page;
237     }
238