From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
commit c3aab9a0bd91b696a852169479b7db1ece6cbf8c upstream.
Functions like filemap_write_and_wait_range() should do nothing if inode has no dirty pages or pages currently under writeback. But they anyway construct struct writeback_control and this does some atomic operations if CONFIG_CGROUP_WRITEBACK=y - on fast path it locks inode->i_lock and updates state of writeback ownership, on slow path might be more work. Current this path is safely avoided only when inode mapping has no pages.
For example generic_file_read_iter() calls filemap_write_and_wait_range() at each O_DIRECT read - pretty hot path.
This patch skips starting new writeback if mapping has no dirty tags set. If writeback is already in progress filemap_write_and_wait_range() will wait for it.
Link: http://lkml.kernel.org/r/156378816804.1087.8607636317907921438.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Jan Kara jack@suse.cz Cc: Tejun Heo tj@kernel.org Cc: Jens Axboe axboe@kernel.dk Cc: Johannes Weiner hannes@cmpxchg.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- mm/filemap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/mm/filemap.c +++ b/mm/filemap.c @@ -338,7 +338,8 @@ int __filemap_fdatawrite_range(struct ad .range_end = end, };
- if (!mapping_cap_writeback_dirty(mapping)) + if (!mapping_cap_writeback_dirty(mapping) || + !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) return 0;
wbc_attach_fdatawrite_inode(&wbc, mapping->host);