Commit 8413ac9d authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

mm: page lock use lock bitops

trylock_page, unlock_page open and close a critical section. Hence,
we can use the lock bitops to get the desired memory ordering.

Also, mark trylock as likely to succeed (and remove the annotation from
callers).
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a978d6f5
...@@ -311,7 +311,7 @@ static inline void __clear_page_locked(struct page *page) ...@@ -311,7 +311,7 @@ static inline void __clear_page_locked(struct page *page)
static inline int trylock_page(struct page *page) static inline int trylock_page(struct page *page)
{ {
return !test_and_set_bit(PG_locked, &page->flags); return (likely(!test_and_set_bit_lock(PG_locked, &page->flags)));
} }
/* /*
......
...@@ -573,16 +573,13 @@ EXPORT_SYMBOL(wait_on_page_bit); ...@@ -573,16 +573,13 @@ EXPORT_SYMBOL(wait_on_page_bit);
* mechananism between PageLocked pages and PageWriteback pages is shared. * mechananism between PageLocked pages and PageWriteback pages is shared.
* But that's OK - sleepers in wait_on_page_writeback() just go back to sleep. * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
* *
* The first mb is necessary to safely close the critical section opened by the * The mb is necessary to enforce ordering between the clear_bit and the read
* test_and_set_bit() to lock the page; the second mb is necessary to enforce * of the waitqueue (to avoid SMP races with a parallel wait_on_page_locked()).
* ordering between the clear_bit and the read of the waitqueue (to avoid SMP
* races with a parallel wait_on_page_locked()).
*/ */
void unlock_page(struct page *page) void unlock_page(struct page *page)
{ {
smp_mb__before_clear_bit(); VM_BUG_ON(!PageLocked(page));
if (!test_and_clear_bit(PG_locked, &page->flags)) clear_bit_unlock(PG_locked, &page->flags);
BUG();
smp_mb__after_clear_bit(); smp_mb__after_clear_bit();
wake_up_page(page, PG_locked); wake_up_page(page, PG_locked);
} }
......
...@@ -422,7 +422,7 @@ void free_swap_and_cache(swp_entry_t entry) ...@@ -422,7 +422,7 @@ void free_swap_and_cache(swp_entry_t entry)
if (p) { if (p) {
if (swap_entry_free(p, swp_offset(entry)) == 1) { if (swap_entry_free(p, swp_offset(entry)) == 1) {
page = find_get_page(&swapper_space, entry.val); page = find_get_page(&swapper_space, entry.val);
if (page && unlikely(!trylock_page(page))) { if (page && !trylock_page(page)) {
page_cache_release(page); page_cache_release(page);
page = NULL; page = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment