mm/filemap: Add __folio_lock_async()

There aren't any actual callers of lock_page_async(), so remove it.
Convert filemap_update_page() to call __folio_lock_async().

__folio_lock_async() is 21 bytes smaller than __lock_page_async(),
but the real savings come from using a folio in filemap_update_page(),
shrinking it from 515 bytes to 404 bytes, saving 110 bytes.  The text
shrinks by 132 bytes in total.
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>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
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>
parent af7f29d9
...@@ -3364,7 +3364,7 @@ static int io_read_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -3364,7 +3364,7 @@ static int io_read_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
} }
/* /*
* This is our waitqueue callback handler, registered through lock_page_async() * This is our waitqueue callback handler, registered through __folio_lock_async()
* when we initially tried to do the IO with the iocb armed our waitqueue. * when we initially tried to do the IO with the iocb armed our waitqueue.
* This gets called when the page is unlocked, and we generally expect that to * This gets called when the page is unlocked, and we generally expect that to
* happen when the page IO is completed and the page is now uptodate. This will * happen when the page IO is completed and the page is now uptodate. This will
......
...@@ -654,7 +654,6 @@ static inline bool wake_page_match(struct wait_page_queue *wait_page, ...@@ -654,7 +654,6 @@ static inline bool wake_page_match(struct wait_page_queue *wait_page,
void __folio_lock(struct folio *folio); void __folio_lock(struct folio *folio);
int __folio_lock_killable(struct folio *folio); int __folio_lock_killable(struct folio *folio);
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);
void unlock_page(struct page *page); void unlock_page(struct page *page);
...@@ -711,22 +710,6 @@ static inline int lock_page_killable(struct page *page) ...@@ -711,22 +710,6 @@ static inline int lock_page_killable(struct page *page)
return folio_lock_killable(page_folio(page)); return folio_lock_killable(page_folio(page));
} }
/*
* lock_page_async - Lock the page, unless this would block. If the page
* is already locked, then queue a callback when the page becomes unlocked.
* This callback can then retry the operation.
*
* Returns 0 if the page is locked successfully, or -EIOCBQUEUED if the page
* was already locked and the callback defined in 'wait' was queued.
*/
static inline int lock_page_async(struct page *page,
struct wait_page_queue *wait)
{
if (!trylock_page(page))
return __lock_page_async(page, wait);
return 0;
}
/* /*
* lock_page_or_retry - Lock the page, unless this would block and the * lock_page_or_retry - Lock the page, unless this would block and the
* caller indicated that it can handle a retry. * caller indicated that it can handle a retry.
......
...@@ -1652,18 +1652,18 @@ int __folio_lock_killable(struct folio *folio) ...@@ -1652,18 +1652,18 @@ int __folio_lock_killable(struct folio *folio)
} }
EXPORT_SYMBOL_GPL(__folio_lock_killable); EXPORT_SYMBOL_GPL(__folio_lock_killable);
int __lock_page_async(struct page *page, struct wait_page_queue *wait) static int __folio_lock_async(struct folio *folio, struct wait_page_queue *wait)
{ {
struct wait_queue_head *q = page_waitqueue(page); struct wait_queue_head *q = page_waitqueue(&folio->page);
int ret = 0; int ret = 0;
wait->page = page; wait->page = &folio->page;
wait->bit_nr = PG_locked; wait->bit_nr = PG_locked;
spin_lock_irq(&q->lock); spin_lock_irq(&q->lock);
__add_wait_queue_entry_tail(q, &wait->wait); __add_wait_queue_entry_tail(q, &wait->wait);
SetPageWaiters(page); folio_set_waiters(folio);
ret = !trylock_page(page); ret = !folio_trylock(folio);
/* /*
* If we were successful now, we know we're still on the * If we were successful now, we know we're still on the
* waitqueue as we're still under the lock. This means it's * waitqueue as we're still under the lock. This means it's
...@@ -2436,6 +2436,7 @@ static int filemap_update_page(struct kiocb *iocb, ...@@ -2436,6 +2436,7 @@ static int filemap_update_page(struct kiocb *iocb,
struct address_space *mapping, struct iov_iter *iter, struct address_space *mapping, struct iov_iter *iter,
struct page *page) struct page *page)
{ {
struct folio *folio = page_folio(page);
int error; int error;
if (iocb->ki_flags & IOCB_NOWAIT) { if (iocb->ki_flags & IOCB_NOWAIT) {
...@@ -2445,40 +2446,40 @@ static int filemap_update_page(struct kiocb *iocb, ...@@ -2445,40 +2446,40 @@ static int filemap_update_page(struct kiocb *iocb,
filemap_invalidate_lock_shared(mapping); filemap_invalidate_lock_shared(mapping);
} }
if (!trylock_page(page)) { if (!folio_trylock(folio)) {
error = -EAGAIN; error = -EAGAIN;
if (iocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO)) if (iocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO))
goto unlock_mapping; goto unlock_mapping;
if (!(iocb->ki_flags & IOCB_WAITQ)) { if (!(iocb->ki_flags & IOCB_WAITQ)) {
filemap_invalidate_unlock_shared(mapping); filemap_invalidate_unlock_shared(mapping);
put_and_wait_on_page_locked(page, TASK_KILLABLE); put_and_wait_on_page_locked(&folio->page, TASK_KILLABLE);
return AOP_TRUNCATED_PAGE; return AOP_TRUNCATED_PAGE;
} }
error = __lock_page_async(page, iocb->ki_waitq); error = __folio_lock_async(folio, iocb->ki_waitq);
if (error) if (error)
goto unlock_mapping; goto unlock_mapping;
} }
error = AOP_TRUNCATED_PAGE; error = AOP_TRUNCATED_PAGE;
if (!page->mapping) if (!folio->mapping)
goto unlock; goto unlock;
error = 0; error = 0;
if (filemap_range_uptodate(mapping, iocb->ki_pos, iter, page)) if (filemap_range_uptodate(mapping, iocb->ki_pos, iter, &folio->page))
goto unlock; goto unlock;
error = -EAGAIN; error = -EAGAIN;
if (iocb->ki_flags & (IOCB_NOIO | IOCB_NOWAIT | IOCB_WAITQ)) if (iocb->ki_flags & (IOCB_NOIO | IOCB_NOWAIT | IOCB_WAITQ))
goto unlock; goto unlock;
error = filemap_read_page(iocb->ki_filp, mapping, page); error = filemap_read_page(iocb->ki_filp, mapping, &folio->page);
goto unlock_mapping; goto unlock_mapping;
unlock: unlock:
unlock_page(page); folio_unlock(folio);
unlock_mapping: unlock_mapping:
filemap_invalidate_unlock_shared(mapping); filemap_invalidate_unlock_shared(mapping);
if (error == AOP_TRUNCATED_PAGE) if (error == AOP_TRUNCATED_PAGE)
put_page(page); folio_put(folio);
return error; return error;
} }
......
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