Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 164440
b: refs/heads/master
c: 2ca4532
h: refs/heads/master
v: v3
  • Loading branch information
Daisuke Nishimura authored and Linus Torvalds committed Sep 22, 2009
1 parent def1ed3 commit b30f7eb
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 31a5639623a487d6db996c8138c9e53fef2e2d91
refs/heads/master: 2ca4532a49be92d7b2766c3244b30fa8bfb0114d
4 changes: 4 additions & 0 deletions trunk/mm/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,10 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
shmem_swp_unmap(entry);
unlock:
spin_unlock(&info->lock);
/*
* add_to_swap_cache() doesn't return -EEXIST, so we can safely
* clear SWAP_HAS_CACHE flag.
*/
swapcache_free(swap, NULL);
redirty:
set_page_dirty(page);
Expand Down
73 changes: 36 additions & 37 deletions trunk/mm/swap_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry)
spin_unlock_irq(&swapper_space.tree_lock);

if (unlikely(error)) {
/*
* Only the context which have set SWAP_HAS_CACHE flag
* would call add_to_swap_cache().
* So add_to_swap_cache() doesn't returns -EEXIST.
*/
VM_BUG_ON(error == -EEXIST);
set_page_private(page, 0UL);
ClearPageSwapCache(page);
page_cache_release(page);
Expand Down Expand Up @@ -146,38 +152,34 @@ int add_to_swap(struct page *page)
VM_BUG_ON(!PageLocked(page));
VM_BUG_ON(!PageUptodate(page));

for (;;) {
entry = get_swap_page();
if (!entry.val)
return 0;
entry = get_swap_page();
if (!entry.val)
return 0;

/*
* Radix-tree node allocations from PF_MEMALLOC contexts could
* completely exhaust the page allocator. __GFP_NOMEMALLOC
* stops emergency reserves from being allocated.
*
* TODO: this could cause a theoretical memory reclaim
* deadlock in the swap out path.
*/
/*
* Add it to the swap cache and mark it dirty
*/
err = add_to_swap_cache(page, entry,
__GFP_HIGH|__GFP_NOMEMALLOC|__GFP_NOWARN);

if (!err) { /* Success */
SetPageDirty(page);
return 1;
} else { /* -ENOMEM radix-tree allocation failure */
/*
* Radix-tree node allocations from PF_MEMALLOC contexts could
* completely exhaust the page allocator. __GFP_NOMEMALLOC
* stops emergency reserves from being allocated.
*
* TODO: this could cause a theoretical memory reclaim
* deadlock in the swap out path.
*/
/*
* Add it to the swap cache and mark it dirty
* add_to_swap_cache() doesn't return -EEXIST, so we can safely
* clear SWAP_HAS_CACHE flag.
*/
err = add_to_swap_cache(page, entry,
__GFP_HIGH|__GFP_NOMEMALLOC|__GFP_NOWARN);

switch (err) {
case 0: /* Success */
SetPageDirty(page);
return 1;
case -EEXIST:
/* Raced with "speculative" read_swap_cache_async */
swapcache_free(entry, NULL);
continue;
default:
/* -ENOMEM radix-tree allocation failure */
swapcache_free(entry, NULL);
return 0;
}
swapcache_free(entry, NULL);
return 0;
}
}

Expand Down Expand Up @@ -318,14 +320,7 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
break;
}

/*
* Associate the page with swap entry in the swap cache.
* May fail (-EEXIST) if there is already a page associated
* with this entry in the swap cache: added by a racing
* read_swap_cache_async, or add_to_swap or shmem_writepage
* re-using the just freed swap entry for an existing page.
* May fail (-ENOMEM) if radix-tree node allocation failed.
*/
/* May fail (-ENOMEM) if radix-tree node allocation failed. */
__set_page_locked(new_page);
SetPageSwapBacked(new_page);
err = __add_to_swap_cache(new_page, entry);
Expand All @@ -341,6 +336,10 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
radix_tree_preload_end();
ClearPageSwapBacked(new_page);
__clear_page_locked(new_page);
/*
* add_to_swap_cache() doesn't return -EEXIST, so we can safely
* clear SWAP_HAS_CACHE flag.
*/
swapcache_free(entry, NULL);
} while (err != -ENOMEM);

Expand Down

0 comments on commit b30f7eb

Please sign in to comment.