forked from luck/tmp_suning_uos_patched
mm: clarify __add_to_swap_cache locking
__add_to_swap_cache unconditionally sets the page locked, which can be a bit alarming to the unsuspecting reader: in the code paths where the page is visible to other CPUs, the page should be (and is) already locked. Instead, just add a check to ensure the page is locked here, and teach the one path relying on the old behaviour to call SetPageLocked itself. [hugh@veritas.com: locking fix] Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
45726cb43d
commit
b55ed81623
|
@ -74,6 +74,7 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
BUG_ON(!PageLocked(page));
|
||||||
BUG_ON(PageSwapCache(page));
|
BUG_ON(PageSwapCache(page));
|
||||||
BUG_ON(PagePrivate(page));
|
BUG_ON(PagePrivate(page));
|
||||||
error = radix_tree_preload(gfp_mask);
|
error = radix_tree_preload(gfp_mask);
|
||||||
|
@ -83,7 +84,6 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
|
||||||
entry.val, page);
|
entry.val, page);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
page_cache_get(page);
|
page_cache_get(page);
|
||||||
SetPageLocked(page);
|
|
||||||
SetPageSwapCache(page);
|
SetPageSwapCache(page);
|
||||||
set_page_private(page, entry.val);
|
set_page_private(page, entry.val);
|
||||||
total_swapcache_pages++;
|
total_swapcache_pages++;
|
||||||
|
@ -99,15 +99,18 @@ static int add_to_swap_cache(struct page *page, swp_entry_t entry)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
BUG_ON(PageLocked(page));
|
||||||
if (!swap_duplicate(entry)) {
|
if (!swap_duplicate(entry)) {
|
||||||
INC_CACHE_INFO(noent_race);
|
INC_CACHE_INFO(noent_race);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
SetPageLocked(page);
|
||||||
error = __add_to_swap_cache(page, entry, GFP_KERNEL);
|
error = __add_to_swap_cache(page, entry, GFP_KERNEL);
|
||||||
/*
|
/*
|
||||||
* Anon pages are already on the LRU, we don't run lru_cache_add here.
|
* Anon pages are already on the LRU, we don't run lru_cache_add here.
|
||||||
*/
|
*/
|
||||||
if (error) {
|
if (error) {
|
||||||
|
ClearPageLocked(page);
|
||||||
swap_free(entry);
|
swap_free(entry);
|
||||||
if (error == -EEXIST)
|
if (error == -EEXIST)
|
||||||
INC_CACHE_INFO(exist_race);
|
INC_CACHE_INFO(exist_race);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user