mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-24 17:23:25 -05:00
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: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: Jeff Layton <jlayton@kernel.org> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Reviewed-by: William Kucharski <william.kucharski@oracle.com> Reviewed-by: David Howells <dhowells@redhat.com> Acked-by: Mike Rapoport <rppt@linux.ibm.com>
This commit is contained in:
parent
af7f29d9e1
commit
ffdc8dabf2
3 changed files with 15 additions and 31 deletions
|
@ -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,
|
||||||
|
|
||||||
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)
|
||||||
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.
|
||||||
|
|
27
mm/filemap.c
27
mm/filemap.c
|
@ -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,
|
||||||
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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue