|
@@ -288,17 +288,14 @@ struct page * lookup_swap_cache(swp_entry_t entry)
|
|
return page;
|
|
return page;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * Locate a page of swap in physical memory, reserving swap cache space
|
|
|
|
- * and reading the disk if it is not already cached.
|
|
|
|
- * A failure return means that either the page allocation failed or that
|
|
|
|
- * the swap entry is no longer in use.
|
|
|
|
- */
|
|
|
|
-struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
|
|
|
|
- struct vm_area_struct *vma, unsigned long addr)
|
|
|
|
|
|
+struct page *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
|
|
|
|
+ struct vm_area_struct *vma, unsigned long addr,
|
|
|
|
+ bool *new_page_allocated)
|
|
{
|
|
{
|
|
struct page *found_page, *new_page = NULL;
|
|
struct page *found_page, *new_page = NULL;
|
|
|
|
+ struct address_space *swapper_space = swap_address_space(entry);
|
|
int err;
|
|
int err;
|
|
|
|
+ *new_page_allocated = false;
|
|
|
|
|
|
do {
|
|
do {
|
|
/*
|
|
/*
|
|
@@ -306,8 +303,7 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
|
|
* called after lookup_swap_cache() failed, re-calling
|
|
* called after lookup_swap_cache() failed, re-calling
|
|
* that would confuse statistics.
|
|
* that would confuse statistics.
|
|
*/
|
|
*/
|
|
- found_page = find_get_page(swap_address_space(entry),
|
|
|
|
- entry.val);
|
|
|
|
|
|
+ found_page = find_get_page(swapper_space, entry.val);
|
|
if (found_page)
|
|
if (found_page)
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -366,7 +362,7 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
|
|
* Initiate read into locked page and return.
|
|
* Initiate read into locked page and return.
|
|
*/
|
|
*/
|
|
lru_cache_add_anon(new_page);
|
|
lru_cache_add_anon(new_page);
|
|
- swap_readpage(new_page);
|
|
|
|
|
|
+ *new_page_allocated = true;
|
|
return new_page;
|
|
return new_page;
|
|
}
|
|
}
|
|
radix_tree_preload_end();
|
|
radix_tree_preload_end();
|
|
@@ -384,6 +380,25 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
|
|
return found_page;
|
|
return found_page;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Locate a page of swap in physical memory, reserving swap cache space
|
|
|
|
+ * and reading the disk if it is not already cached.
|
|
|
|
+ * A failure return means that either the page allocation failed or that
|
|
|
|
+ * the swap entry is no longer in use.
|
|
|
|
+ */
|
|
|
|
+struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
|
|
|
|
+ struct vm_area_struct *vma, unsigned long addr)
|
|
|
|
+{
|
|
|
|
+ bool page_was_allocated;
|
|
|
|
+ struct page *retpage = __read_swap_cache_async(entry, gfp_mask,
|
|
|
|
+ vma, addr, &page_was_allocated);
|
|
|
|
+
|
|
|
|
+ if (page_was_allocated)
|
|
|
|
+ swap_readpage(retpage);
|
|
|
|
+
|
|
|
|
+ return retpage;
|
|
|
|
+}
|
|
|
|
+
|
|
static unsigned long swapin_nr_pages(unsigned long offset)
|
|
static unsigned long swapin_nr_pages(unsigned long offset)
|
|
{
|
|
{
|
|
static unsigned long prev_offset;
|
|
static unsigned long prev_offset;
|