[RFC] mm: optimise generic_file_read_iter

From: Pavel Begunkov
Date: Fri Aug 06 2021 - 07:43:22 EST


Unless direct I/O path of generic_file_read_iter() ended up with an
error or a short read, it doesn't use inode. So, load inode and size
later, only when they're needed. This cuts two memory reads and also
imrpoves code generation, e.g. loads from stack.

Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx>
---

NOTE: as a side effect, it reads inode->i_size after ->direct_IO(), and
I'm not sure whether that's valid, so would be great to get feedback
from someone who knows better.

mm/filemap.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mm/filemap.c b/mm/filemap.c
index d1458ecf2f51..0030c454ec35 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2658,10 +2658,8 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
if (iocb->ki_flags & IOCB_DIRECT) {
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
- struct inode *inode = mapping->host;
- loff_t size;
+ struct inode *inode;

- size = i_size_read(inode);
if (iocb->ki_flags & IOCB_NOWAIT) {
if (filemap_range_needs_writeback(mapping, iocb->ki_pos,
iocb->ki_pos + count - 1))
@@ -2693,8 +2691,10 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
* the rest of the read. Buffered reads will not work for
* DAX files, so don't bother trying.
*/
- if (retval < 0 || !count || iocb->ki_pos >= size ||
- IS_DAX(inode))
+ if (retval < 0 || !count)
+ return retval;
+ inode = mapping->host;
+ if (iocb->ki_pos >= i_size_read(inode) || IS_DAX(inode))
return retval;
}

--
2.32.0