lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <07bd408d6cad95166b776911823b40044160b434.1628248975.git.asml.silence@gmail.com>
Date:   Fri,  6 Aug 2021 12:42:43 +0100
From:   Pavel Begunkov <asml.silence@...il.com>
To:     Andrew Morton <akpm@...ux-foundation.org>, linux-mm@...ck.org
Cc:     Alexander Viro <viro@...iv.linux.org.uk>,
        linux-fsdevel@...r.kernel.org, Jens Axboe <axboe@...nel.dk>,
        linux-kernel@...r.kernel.org
Subject: [RFC] mm: optimise generic_file_read_iter

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@...il.com>
---

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ