All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Matthew Wilcox <willy@infradead.org>
Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-block@vger.kernel.org,
	Jens Axboe <axboe@kernel.dk>,
	Christoph Hellwig <hch@infradead.org>
Subject: Re: [PATCH v2 19/28] iomap: Convert __iomap_zero_iter to use a folio
Date: Thu, 16 Dec 2021 11:36:14 -0800	[thread overview]
Message-ID: <20211216193614.GA27676@magnolia> (raw)
In-Reply-To: <YbJ3O1qf+9p/HWka@casper.infradead.org>

On Thu, Dec 09, 2021 at 09:38:03PM +0000, Matthew Wilcox wrote:
> On Mon, Nov 08, 2021 at 04:05:42AM +0000, Matthew Wilcox (Oracle) wrote:
> > +++ b/fs/iomap/buffered-io.c
> > @@ -881,17 +881,20 @@ EXPORT_SYMBOL_GPL(iomap_file_unshare);
> >  
> >  static s64 __iomap_zero_iter(struct iomap_iter *iter, loff_t pos, u64 length)
> >  {
> > +	struct folio *folio;
> >  	struct page *page;
> >  	int status;
> > -	unsigned offset = offset_in_page(pos);
> > -	unsigned bytes = min_t(u64, PAGE_SIZE - offset, length);
> > +	size_t offset, bytes;
> >  
> > -	status = iomap_write_begin(iter, pos, bytes, &page);
> > +	status = iomap_write_begin(iter, pos, length, &page);
> 
> This turned out to be buggy.  Darrick and I figured out why his tests
> were failing and mine weren't; this only shows up with a 4kB block
> size filesystem and I was only testing with 1kB block size filesystems.
> (at least on x86; I haven't figured out why it passes with 1kB block size
> filesystems, so I'm not sure what would be true on other filesystems).
> iomap_write_begin() is not prepared to deal with a length that spans a
> page boundary.  So I'm replacing this patch with the following patches
> (whitespace damaged; pick them up from
> https://git.infradead.org/users/willy/linux.git/tag/refs/tags/iomap-folio-5.17c
> if you want to compile them):
> 
> commit 412212960b72
> Author: Matthew Wilcox (Oracle) <willy@infradead.org>
> Date:   Thu Dec 9 15:47:44 2021 -0500
> 
>     iomap: Allow iomap_write_begin() to be called with the full length
> 
>     In the future, we want write_begin to know the entire length of the
>     write so that it can choose to allocate large folios.  Pass the full
>     length in from __iomap_zero_iter() and limit it where necessary.
> 
>     Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> 
> diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
> index d67108489148..9270db17c435 100644
> --- a/fs/gfs2/bmap.c
> +++ b/fs/gfs2/bmap.c
> @@ -968,6 +968,9 @@ static int gfs2_iomap_page_prepare(struct inode *inode, loff_t pos,
>         struct gfs2_sbd *sdp = GFS2_SB(inode);
>         unsigned int blocks;
> 
> +       /* gfs2 does not support large folios yet */
> +       if (len > PAGE_SIZE)
> +               len = PAGE_SIZE;

This is awkward -- gfs2 doesn't set the mapping flag to indicate that it
supports large folios, so it should never be asked to deal with more
than a page at a time.  Shouldn't iomap_write_begin clamp its len
argument to PAGE_SIZE at the start if the mapping doesn't have the large
folios flag set?

--D

>         blocks = ((pos & blockmask) + len + blockmask) >> inode->i_blkbits;
>         return gfs2_trans_begin(sdp, RES_DINODE + blocks, 0);
>  }
> diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
> index 8d7a67655b60..67fcd3b9928d 100644
> --- a/fs/iomap/buffered-io.c
> +++ b/fs/iomap/buffered-io.c
> @@ -632,6 +632,8 @@ static int iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
>                 goto out_no_page;
>         }
>         folio = page_folio(page);
> +       if (pos + len > folio_pos(folio) + folio_size(folio))
> +               len = folio_pos(folio) + folio_size(folio) - pos;
> 
>         if (srcmap->type == IOMAP_INLINE)
>                 status = iomap_write_begin_inline(iter, page);
> @@ -891,16 +893,19 @@ static s64 __iomap_zero_iter(struct iomap_iter *iter, loff
> _t pos, u64 length)
>         struct page *page;
>         int status;
>         unsigned offset = offset_in_page(pos);
> -       unsigned bytes = min_t(u64, PAGE_SIZE - offset, length);
> 
> -       status = iomap_write_begin(iter, pos, bytes, &page);
> +       if (length > UINT_MAX)
> +               length = UINT_MAX;
> +       status = iomap_write_begin(iter, pos, length, &page);
>         if (status)
>                 return status;
> +       if (length > PAGE_SIZE - offset)
> +               length = PAGE_SIZE - offset;
> 
> -       zero_user(page, offset, bytes);
> +       zero_user(page, offset, length);
>         mark_page_accessed(page);
> 
> -       return iomap_write_end(iter, pos, bytes, bytes, page);
> +       return iomap_write_end(iter, pos, length, length, page);
>  }
> 
>  static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero)
> 
> 
> commit 78c747a1b3a1
> Author: Matthew Wilcox (Oracle) <willy@infradead.org>
> Date:   Fri Nov 5 14:24:09 2021 -0400
> 
>     iomap: Convert __iomap_zero_iter to use a folio
>     
>     The zero iterator can work in folio-sized chunks instead of page-sized
>     chunks.  This will save a lot of page cache lookups if the file is cached
>     in large folios.
>     
>     Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
>     Reviewed-by: Christoph Hellwig <hch@lst.de>
>     Reviewed-by: Darrick J. Wong <djwong@kernel.org>
> 
> diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
> index 67fcd3b9928d..bbde6d4f27cd 100644
> --- a/fs/iomap/buffered-io.c
> +++ b/fs/iomap/buffered-io.c
> @@ -890,20 +890,23 @@ EXPORT_SYMBOL_GPL(iomap_file_unshare);
>  
>  static s64 __iomap_zero_iter(struct iomap_iter *iter, loff_t pos, u64 length)
>  {
> +       struct folio *folio;
>         struct page *page;
>         int status;
> -       unsigned offset = offset_in_page(pos);
> +       size_t offset;
>  
>         if (length > UINT_MAX)
>                 length = UINT_MAX;
>         status = iomap_write_begin(iter, pos, length, &page);
>         if (status)
>                 return status;
> -       if (length > PAGE_SIZE - offset)
> -               length = PAGE_SIZE - offset;
> +       folio = page_folio(page);
>  
> -       zero_user(page, offset, length);
> -       mark_page_accessed(page);
> +       offset = offset_in_folio(folio, pos);
> +       if (length > folio_size(folio) - offset)
> +               length = folio_size(folio) - offset;
> +       folio_zero_range(folio, offset, length);
> +       folio_mark_accessed(folio);
>  
>         return iomap_write_end(iter, pos, length, length, page);
>  }
> 
> 
> The xfstests that Darrick identified as failing all passed.  Running a
> full sweep now; then I'll re-run with a 1kB filesystem to be sure that
> still passes.  Then I'll send another pull request.

  parent reply	other threads:[~2021-12-16 19:36 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-08  4:05 [PATCH v2 00/28] iomap/xfs folio patches Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 01/28] csky,sparc: Declare flush_dcache_folio() Matthew Wilcox (Oracle)
2021-11-09  8:36   ` Christoph Hellwig
2021-11-15 15:54     ` Matthew Wilcox
2021-11-16  6:33       ` Christoph Hellwig
2021-11-16 21:49         ` Matthew Wilcox
2021-11-17  9:52           ` Geert Uytterhoeven
2021-11-08  4:05 ` [PATCH v2 02/28] mm: Add functions to zero portions of a folio Matthew Wilcox (Oracle)
2021-11-09  8:40   ` Christoph Hellwig
2021-11-17  4:45   ` Darrick J. Wong
2021-11-17 14:07     ` Matthew Wilcox
2021-11-17 17:07       ` Darrick J. Wong
2021-11-18 15:55         ` Matthew Wilcox
2021-11-18 17:26           ` Darrick J. Wong
2021-11-18 20:08             ` Matthew Wilcox
2021-11-08  4:05 ` [PATCH v2 03/28] fs: Remove FS_THP_SUPPORT Matthew Wilcox (Oracle)
2021-11-17  4:36   ` Darrick J. Wong
2021-11-08  4:05 ` [PATCH v2 04/28] fs: Rename AS_THP_SUPPORT and mapping_thp_support Matthew Wilcox (Oracle)
2021-11-09  8:41   ` Christoph Hellwig
2021-11-15 16:03     ` Matthew Wilcox
2021-11-16  6:33       ` Christoph Hellwig
2021-11-08  4:05 ` [PATCH v2 05/28] block: Add bio_add_folio() Matthew Wilcox (Oracle)
2021-11-17  4:48   ` Darrick J. Wong
2021-11-08  4:05 ` [PATCH v2 06/28] block: Add bio_for_each_folio_all() Matthew Wilcox (Oracle)
2021-11-17  4:48   ` Darrick J. Wong
2021-11-08  4:05 ` [PATCH v2 07/28] fs/buffer: Convert __block_write_begin_int() to take a folio Matthew Wilcox (Oracle)
2021-11-09  8:42   ` Christoph Hellwig
2021-11-17  4:35   ` Darrick J. Wong
2021-11-08  4:05 ` [PATCH v2 08/28] iomap: Convert to_iomap_page " Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 09/28] iomap: Convert iomap_page_create " Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 10/28] iomap: Convert iomap_page_release " Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 11/28] iomap: Convert iomap_releasepage to use " Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 12/28] iomap: Add iomap_invalidate_folio Matthew Wilcox (Oracle)
2021-11-17  2:20   ` Darrick J. Wong
2021-11-08  4:05 ` [PATCH v2 13/28] iomap: Pass the iomap_page into iomap_set_range_uptodate Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 14/28] iomap: Convert bio completions to use folios Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 15/28] iomap: Use folio offsets instead of page offsets Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 16/28] iomap: Convert iomap_read_inline_data to take a folio Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 17/28] iomap: Convert readahead and readpage to use " Matthew Wilcox (Oracle)
2021-11-09  8:43   ` Christoph Hellwig
2021-11-08  4:05 ` [PATCH v2 18/28] iomap: Convert iomap_page_mkwrite " Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 19/28] iomap: Convert __iomap_zero_iter " Matthew Wilcox (Oracle)
2021-11-09  8:47   ` Christoph Hellwig
2021-11-17  2:24   ` Darrick J. Wong
2021-11-17 14:20     ` Matthew Wilcox
2021-12-09 21:38   ` Matthew Wilcox
2021-12-10 16:19     ` Matthew Wilcox
2021-12-13  7:34       ` Christoph Hellwig
2021-12-13 18:08         ` Matthew Wilcox
2021-12-16 19:36     ` Darrick J. Wong [this message]
2021-12-16 20:43       ` Matthew Wilcox
2021-11-08  4:05 ` [PATCH v2 20/28] iomap: Convert iomap_write_begin() and iomap_write_end() to folios Matthew Wilcox (Oracle)
2021-11-17  4:31   ` Darrick J. Wong
2021-11-17 14:31     ` Matthew Wilcox
2021-11-17 17:10       ` Darrick J. Wong
2021-11-08  4:05 ` [PATCH v2 21/28] iomap: Convert iomap_write_end_inline to take a folio Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 22/28] iomap,xfs: Convert ->discard_page to ->discard_folio Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 23/28] iomap: Simplify iomap_writepage_map() Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 24/28] iomap: Simplify iomap_do_writepage() Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 25/28] iomap: Convert iomap_add_to_ioend() to take a folio Matthew Wilcox (Oracle)
2021-11-17  4:34   ` Darrick J. Wong
2021-11-08  4:05 ` [PATCH v2 26/28] iomap: Convert iomap_migrate_page() to use folios Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 27/28] iomap: Support multi-page folios in invalidatepage Matthew Wilcox (Oracle)
2021-11-08  4:05 ` [PATCH v2 28/28] xfs: Support multi-page folios Matthew Wilcox (Oracle)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211216193614.GA27676@magnolia \
    --to=djwong@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=hch@infradead.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.