On Tue, Jun 23, 2020 at 2:52 AM Dave Chinner <david@xxxxxxxxxxxxx> wrote: > On Mon, Jun 22, 2020 at 04:35:05PM +0200, Andreas Gruenbacher wrote: > > On Mon, Jun 22, 2020 at 2:32 AM Dave Chinner <david@xxxxxxxxxxxxx> wrote: > > > On Fri, Jun 19, 2020 at 08:50:36AM -0700, Matthew Wilcox wrote: > > > > > > > > This patch lifts the IOCB_CACHED idea expressed by Andreas to the VFS. > > > > The advantage of this patch is that we can avoid taking any filesystem > > > > lock, as long as the pages being accessed are in the cache (and we don't > > > > need to readahead any pages into the cache). We also avoid an indirect > > > > function call in these cases. > > > > > > What does this micro-optimisation actually gain us except for more > > > complexity in the IO path? > > > > > > i.e. if a filesystem lock has such massive overhead that it slows > > > down the cached readahead path in production workloads, then that's > > > something the filesystem needs to address, not unconditionally > > > bypass the filesystem before the IO gets anywhere near it. > > > > I'm fine with not moving that functionality into the VFS. The problem > > I have in gfs2 is that taking glocks is really expensive. Part of that > > overhead is accidental, but we definitely won't be able to fix it in > > the short term. So something like the IOCB_CACHED flag that prevents > > generic_file_read_iter from issuing readahead I/O would save the day > > for us. Does that idea stand a chance? > > I have no problem with a "NOREADAHEAD" flag being passed to > generic_file_read_iter(). It's not a "already cached" flag though, > it's a "don't start any IO" directive, just like the NOWAIT flag is > a "don't block on locks or IO in progress" directive and not an > "already cached" flag. Readahead is something we should be doing, > unless a filesystem has a very good reason not to, such as the gfs2 > locking case here... The requests coming in can have the IOCB_NOWAIT flag set or cleared. The idea was to have an additional flag that implies IOCB_NOWAIT so that you can do: iocb->ki_flags |= IOCB_NOIO; generic_file_read_iter() if ("failed because of IOCB_NOIO") { if ("failed because of IOCB_NOWAIT") return -EAGAIN; iocb->ki_flags &= ~IOCB_NOIO; "locking" generic_file_read_iter() "unlocking" } without having to save iocb->ki_flags. The alternative would be: int flags = iocb->ki_flags; iocb->ki_flags |= IOCB_NOIO | IOCB_NOWAIT; ret = generic_file_read_iter() if ("failed because of IOCB_NOIO or IOCB_NOWAIT") { if ("failed because of IOCB_NOWAIT" && (flags & IOCB_NOWAIT)) return -EAGAIN; iocb->ki_flags &= ~IOCB_NOIO; "locking" generic_file_read_iter() "unlocking" } Andreas