提交 b55ed816 编写于 作者: N Nick Piggin 提交者: Linus Torvalds

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: NNick Piggin <npiggin@suse.de>
Signed-off-by: NHugh Dickins <hugh@veritas.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 45726cb4
...@@ -74,6 +74,7 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry, ...@@ -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, ...@@ -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) ...@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册