lkml.org 
[lkml]   [2020]   [Jun]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [PATCH 05/15] mm: allow read-ahead with IOCB_NOWAIT set
    From
    Date
    On 6/24/20 9:00 AM, Jens Axboe wrote:
    > On 6/23/20 7:46 PM, Matthew Wilcox wrote:
    >> On Wed, Jun 24, 2020 at 11:02:53AM +1000, Dave Chinner wrote:
    >>> On Thu, Jun 18, 2020 at 08:43:45AM -0600, Jens Axboe wrote:
    >>>> The read-ahead shouldn't block, so allow it to be done even if
    >>>> IOCB_NOWAIT is set in the kiocb.
    >>>
    >>> Doesn't think break preadv2(RWF_NOWAIT) semantics for on buffered
    >>> reads? i.e. this can now block on memory allocation for the page
    >>> cache, which is something RWF_NOWAIT IO should not do....
    >>
    >> Yes. This eventually ends up in page_cache_readahead_unbounded()
    >> which gets its gfp flags from readahead_gfp_mask(mapping).
    >>
    >> I'd be quite happy to add a gfp_t to struct readahead_control.
    >> The other thing I've been looking into for other reasons is adding
    >> a memalloc_nowait_{save,restore}, which would avoid passing down
    >> the gfp_t.
    >
    > That was my first thought, having the memalloc_foo_save/restore for
    > this. I don't think adding a gfp_t to readahead_control is going
    > to be super useful, seems like the kind of thing that should be
    > non-blocking by default.

    We're already doing memalloc_nofs_save/restore in
    page_cache_readahead_unbounded(), so I think all we need is to just do a
    noio dance in generic_file_buffered_read() and that should be enough.

    diff --git a/mm/filemap.c b/mm/filemap.c
    index a5b1fa8f7ce4..c29d4b310ed6 100644
    --- a/mm/filemap.c
    +++ b/mm/filemap.c
    @@ -41,6 +41,7 @@
    #include <linux/delayacct.h>
    #include <linux/psi.h>
    #include <linux/ramfs.h>
    +#include <linux/sched/mm.h>
    #include "internal.h"

    #define CREATE_TRACE_POINTS
    @@ -2011,6 +2012,7 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
    struct address_space *mapping = filp->f_mapping;
    struct inode *inode = mapping->host;
    struct file_ra_state *ra = &filp->f_ra;
    + const bool nowait = (iocb->ki_flags & IOCB_NOWAIT) != 0;
    loff_t *ppos = &iocb->ki_pos;
    pgoff_t index;
    pgoff_t last_index;
    @@ -2044,9 +2046,15 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,

    page = find_get_page(mapping, index);
    if (!page) {
    + unsigned int flags;
    +
    + if (nowait)
    + flags = memalloc_noio_save();
    page_cache_sync_readahead(mapping,
    ra, filp,
    index, last_index - index);
    + if (nowait)
    + memalloc_noio_restore(flags);
    page = find_get_page(mapping, index);
    if (unlikely(page == NULL))
    goto no_cached_page;
    @@ -2070,7 +2078,7 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
    error = wait_on_page_locked_async(page,
    iocb->ki_waitq);
    } else {
    - if (iocb->ki_flags & IOCB_NOWAIT) {
    + if (nowait) {
    put_page(page);
    goto would_block;
    }
    @@ -2185,7 +2193,7 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
    }

    readpage:
    - if (iocb->ki_flags & IOCB_NOWAIT) {
    + if (nowait) {
    unlock_page(page);
    put_page(page);
    goto would_block;
    --
    Jens Axboe

    \
     
     \ /
      Last update: 2020-06-24 17:36    [W:5.598 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site