mm/filemap: Add folio_unlock()

Convert unlock_page() to call folio_unlock().  By using a folio we
avoid a call to compound_head().  This shortens the function from 39
bytes to 25 and removes 4 instructions on x86-64.  Because we still
have unlock_page(), it's a net increase of 16 bytes of text for the
kernel as a whole, but any path that uses folio_unlock() will execute
4 fewer instructions.
Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarJeff Layton <jlayton@kernel.org>
Acked-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reviewed-by: default avatarWilliam Kucharski <william.kucharski@oracle.com>
Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarMike Rapoport <rppt@linux.ibm.com>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
parent 2f52578f
...@@ -657,7 +657,8 @@ extern int __lock_page_killable(struct page *page); ...@@ -657,7 +657,8 @@ extern int __lock_page_killable(struct page *page);
extern int __lock_page_async(struct page *page, struct wait_page_queue *wait); extern int __lock_page_async(struct page *page, struct wait_page_queue *wait);
extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm, extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
unsigned int flags); unsigned int flags);
extern void unlock_page(struct page *page); void unlock_page(struct page *page);
void folio_unlock(struct folio *folio);
/* /*
* Return true if the page was successfully locked * Return true if the page was successfully locked
......
...@@ -1490,29 +1490,24 @@ static inline bool clear_bit_unlock_is_negative_byte(long nr, volatile void *mem ...@@ -1490,29 +1490,24 @@ static inline bool clear_bit_unlock_is_negative_byte(long nr, volatile void *mem
#endif #endif
/** /**
* unlock_page - unlock a locked page * folio_unlock - Unlock a locked folio.
* @page: the page * @folio: The folio.
* *
* Unlocks the page and wakes up sleepers in wait_on_page_locked(). * Unlocks the folio and wakes up any thread sleeping on the page lock.
* Also wakes sleepers in wait_on_page_writeback() because the wakeup
* mechanism between PageLocked pages and PageWriteback pages is shared.
* But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
* *
* Note that this depends on PG_waiters being the sign bit in the byte * Context: May be called from interrupt or process context. May not be
* that contains PG_locked - thus the BUILD_BUG_ON(). That allows us to * called from NMI context.
* clear the PG_locked bit and test PG_waiters at the same time fairly
* portably (architectures that do LL/SC can test any bit, while x86 can
* test the sign bit).
*/ */
void unlock_page(struct page *page) void folio_unlock(struct folio *folio)
{ {
/* Bit 7 allows x86 to check the byte's sign bit */
BUILD_BUG_ON(PG_waiters != 7); BUILD_BUG_ON(PG_waiters != 7);
page = compound_head(page); BUILD_BUG_ON(PG_locked > 7);
VM_BUG_ON_PAGE(!PageLocked(page), page); VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
if (clear_bit_unlock_is_negative_byte(PG_locked, &page->flags)) if (clear_bit_unlock_is_negative_byte(PG_locked, folio_flags(folio, 0)))
wake_up_page_bit(page, PG_locked); wake_up_page_bit(&folio->page, PG_locked);
} }
EXPORT_SYMBOL(unlock_page); EXPORT_SYMBOL(folio_unlock);
/** /**
* end_page_private_2 - Clear PG_private_2 and release any waiters * end_page_private_2 - Clear PG_private_2 and release any waiters
......
...@@ -11,3 +11,9 @@ struct address_space *page_mapping(struct page *page) ...@@ -11,3 +11,9 @@ struct address_space *page_mapping(struct page *page)
return folio_mapping(page_folio(page)); return folio_mapping(page_folio(page));
} }
EXPORT_SYMBOL(page_mapping); EXPORT_SYMBOL(page_mapping);
void unlock_page(struct page *page)
{
return folio_unlock(page_folio(page));
}
EXPORT_SYMBOL(unlock_page);
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