From dc185ab836d41729f15b2925a59c7dc29ae72377 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Tue, 9 Mar 2021 13:48:03 -0500 Subject: [PATCH] mm/writeback: Add pageset_write_one Transform write_one_page() into pageset_write_one() and add a compatibility wrapper. Also move the declaration to pagemap.h as this is page cache functionality that doesn't need to be used by the rest of the kernel. Saves 58 bytes of kernel text. While pageset_write_one() is 101 bytes smaller than write_one_page(), the inlined call to page_pageset() expands each caller. There are fewer than ten callers so it doesn't seem worth putting a wrapper in the core. Signed-off-by: Matthew Wilcox (Oracle) Reviewed-by: David Howells --- include/linux/mm.h | 4 ---- include/linux/pagemap.h | 5 +++++ mm/page-writeback.c | 30 +++++++++++++++--------------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index aae92c8c0668d..db66b45d855f2 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2787,10 +2787,6 @@ extern vm_fault_t filemap_map_pages(struct vm_fault *vmf, pgoff_t start_pgoff, pgoff_t end_pgoff); extern vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf); -/* mm/page-writeback.c */ -int __must_check write_one_page(struct page *page); -void task_dirty_inc(struct task_struct *tsk); - extern unsigned long stack_guard_gap; /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */ extern int expand_stack(struct vm_area_struct *vma, unsigned long address); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 1cac000bdbf88..a7caa305e8d82 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -804,6 +804,11 @@ static inline void cancel_dirty_page(struct page *page) } bool pageset_clear_dirty_for_io(struct pageset *pageset); bool clear_page_dirty_for_io(struct page *page); +int __must_check pageset_write_one(struct pageset *pageset); +static inline int __must_check write_one_page(struct page *page) +{ + return pageset_write_one(page_pageset(page)); +} int __set_page_dirty_nobuffers(struct page *page); int __set_page_dirty_no_writeback(struct page *page); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 0b82f2c4da46e..071f9cca68371 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2364,44 +2364,44 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc) } /** - * write_one_page - write out a single page and wait on I/O - * @page: the page to write + * pageset_write_one - write out a single pageset and wait on I/O. + * @pageset: The pageset to write. * - * The page must be locked by the caller and will be unlocked upon return. + * The pageset must be locked by the caller and will be unlocked upon return. * * Note that the mapping's AS_EIO/AS_ENOSPC flags will be cleared when this * function returns. * * Return: %0 on success, negative error code otherwise */ -int write_one_page(struct page *page) +int pageset_write_one(struct pageset *pageset) { - struct address_space *mapping = page->mapping; + struct address_space *mapping = pageset->mapping; int ret = 0; struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, - .nr_to_write = 1, + .nr_to_write = pageset_nr_pages(pageset), }; - BUG_ON(!PageLocked(page)); + BUG_ON(!pageset_test_locked(pageset)); - wait_on_page_writeback(page); + pageset_wait_writeback(pageset); - if (clear_page_dirty_for_io(page)) { - get_page(page); - ret = mapping->a_ops->writepage(page, &wbc); + if (pageset_clear_dirty_for_io(pageset)) { + pageset_get(pageset); + ret = mapping->a_ops->writepage(&pageset->page, &wbc); if (ret == 0) - wait_on_page_writeback(page); - put_page(page); + pageset_wait_writeback(pageset); + pageset_put(pageset); } else { - unlock_page(page); + pageset_unlock(pageset); } if (!ret) ret = filemap_check_errors(mapping); return ret; } -EXPORT_SYMBOL(write_one_page); +EXPORT_SYMBOL(pageset_write_one); /* * For address_spaces which do not use buffers nor write back. -- 2.49.0