diff mbox series

[3/3] xfs/559: adapt to kernels that use large folios for writes

Message ID 169335022920.3517899.399149462227894457.stgit@frogsfrogsfrogs (mailing list archive)
State New, archived
Headers show
Series fstests: updates for Linux 6.6 | expand

Commit Message

Darrick J. Wong Aug. 29, 2023, 11:03 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

The write invalidation code in iomap can only be triggered for writes
that span multiple folios.  If the kernel reports a huge page size,
scale up the write size.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 tests/xfs/559 |   29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

Comments

Zorro Lang Sept. 1, 2023, 7:08 p.m. UTC | #1
On Tue, Aug 29, 2023 at 04:03:49PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> The write invalidation code in iomap can only be triggered for writes
> that span multiple folios.  If the kernel reports a huge page size,
> scale up the write size.
> 
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>  tests/xfs/559 |   29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
> 
> 
> diff --git a/tests/xfs/559 b/tests/xfs/559
> index cffe5045a5..64fc16ebfd 100755
> --- a/tests/xfs/559
> +++ b/tests/xfs/559
> @@ -42,11 +42,38 @@ $XFS_IO_PROG -c 'chattr -x' $SCRATCH_MNT &> $seqres.full
>  _require_pagecache_access $SCRATCH_MNT
>  
>  blocks=10
> -blksz=$(_get_page_size)
> +
> +# If this kernel advertises huge page support, it's possible that it could be
> +# using large folios for the page cache writes.  It is necessary to write
> +# multiple folios (large or regular) to triggering the write invalidation,
> +# so we'll scale the test write size accordingly.
> +blksz=$(_get_hugepagesize)

Isn't _require_hugepages needed if _get_hugepagesize is used?

Thanks,
Zorro

> +base_pagesize=$(_get_page_size)
> +test -z "$blksz" && blksz=${base_pagesize}
>  filesz=$((blocks * blksz))
>  dirty_offset=$(( filesz - 1 ))
>  write_len=$(( ( (blocks - 1) * blksz) + 1 ))
>  
> +# The write invalidation that we're testing below can only occur as part of
> +# a single large write.  The kernel limits writes to one base page less than
> +# 2GiB to prevent lengthy IOs and integer overflows.  If the block size is so
> +# huge (e.g. 512M huge pages on arm64) that we'd exceed that, reduce the number
> +# of blocks to get us under the limit.
> +max_writesize=$((2147483647 - base_pagesize))
> +if ((write_len > max_writesize)); then
> +	blocks=$(( ( (max_writesize - 1) / blksz) + 1))
> +	# We need at least three blocks in the file to test invalidation
> +	# between writes to multiple folios.  If we drop below that,
> +	# reconfigure ourselves with base pages and hope for the best.
> +	if ((blocks < 3)); then
> +		blksz=$base_pagesize
> +		blocks=10
> +	fi
> +	filesz=$((blocks * blksz))
> +	dirty_offset=$(( filesz - 1 ))
> +	write_len=$(( ( (blocks - 1) * blksz) + 1 ))
> +fi
> +
>  # Create a large file with a large unwritten range.
>  $XFS_IO_PROG -f -c "falloc 0 $filesz" $SCRATCH_MNT/file >> $seqres.full
>  
>
Darrick J. Wong Sept. 2, 2023, 4:56 a.m. UTC | #2
On Sat, Sep 02, 2023 at 03:08:02AM +0800, Zorro Lang wrote:
> On Tue, Aug 29, 2023 at 04:03:49PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > The write invalidation code in iomap can only be triggered for writes
> > that span multiple folios.  If the kernel reports a huge page size,
> > scale up the write size.
> > 
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > ---
> >  tests/xfs/559 |   29 ++++++++++++++++++++++++++++-
> >  1 file changed, 28 insertions(+), 1 deletion(-)
> > 
> > 
> > diff --git a/tests/xfs/559 b/tests/xfs/559
> > index cffe5045a5..64fc16ebfd 100755
> > --- a/tests/xfs/559
> > +++ b/tests/xfs/559
> > @@ -42,11 +42,38 @@ $XFS_IO_PROG -c 'chattr -x' $SCRATCH_MNT &> $seqres.full
> >  _require_pagecache_access $SCRATCH_MNT
> >  
> >  blocks=10
> > -blksz=$(_get_page_size)
> > +
> > +# If this kernel advertises huge page support, it's possible that it could be
> > +# using large folios for the page cache writes.  It is necessary to write
> > +# multiple folios (large or regular) to triggering the write invalidation,
> > +# so we'll scale the test write size accordingly.
> > +blksz=$(_get_hugepagesize)
> 
> Isn't _require_hugepages needed if _get_hugepagesize is used?

Nope -- if the kernel doesn't support hugepages, then _get_hugepagesize
returns the empty string...

> Thanks,
> Zorro
> 
> > +base_pagesize=$(_get_page_size)
> > +test -z "$blksz" && blksz=${base_pagesize}

...and this line will substitute in the base page size as the block size.

--D

> >  filesz=$((blocks * blksz))
> >  dirty_offset=$(( filesz - 1 ))
> >  write_len=$(( ( (blocks - 1) * blksz) + 1 ))
> >  
> > +# The write invalidation that we're testing below can only occur as part of
> > +# a single large write.  The kernel limits writes to one base page less than
> > +# 2GiB to prevent lengthy IOs and integer overflows.  If the block size is so
> > +# huge (e.g. 512M huge pages on arm64) that we'd exceed that, reduce the number
> > +# of blocks to get us under the limit.
> > +max_writesize=$((2147483647 - base_pagesize))
> > +if ((write_len > max_writesize)); then
> > +	blocks=$(( ( (max_writesize - 1) / blksz) + 1))
> > +	# We need at least three blocks in the file to test invalidation
> > +	# between writes to multiple folios.  If we drop below that,
> > +	# reconfigure ourselves with base pages and hope for the best.
> > +	if ((blocks < 3)); then
> > +		blksz=$base_pagesize
> > +		blocks=10
> > +	fi
> > +	filesz=$((blocks * blksz))
> > +	dirty_offset=$(( filesz - 1 ))
> > +	write_len=$(( ( (blocks - 1) * blksz) + 1 ))
> > +fi
> > +
> >  # Create a large file with a large unwritten range.
> >  $XFS_IO_PROG -f -c "falloc 0 $filesz" $SCRATCH_MNT/file >> $seqres.full
> >  
> > 
>
Zorro Lang Sept. 2, 2023, 5:21 a.m. UTC | #3
On Fri, Sep 01, 2023 at 09:56:29PM -0700, Darrick J. Wong wrote:
> On Sat, Sep 02, 2023 at 03:08:02AM +0800, Zorro Lang wrote:
> > On Tue, Aug 29, 2023 at 04:03:49PM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <djwong@kernel.org>
> > > 
> > > The write invalidation code in iomap can only be triggered for writes
> > > that span multiple folios.  If the kernel reports a huge page size,
> > > scale up the write size.
> > > 
> > > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > > ---
> > >  tests/xfs/559 |   29 ++++++++++++++++++++++++++++-
> > >  1 file changed, 28 insertions(+), 1 deletion(-)
> > > 
> > > 
> > > diff --git a/tests/xfs/559 b/tests/xfs/559
> > > index cffe5045a5..64fc16ebfd 100755
> > > --- a/tests/xfs/559
> > > +++ b/tests/xfs/559
> > > @@ -42,11 +42,38 @@ $XFS_IO_PROG -c 'chattr -x' $SCRATCH_MNT &> $seqres.full
> > >  _require_pagecache_access $SCRATCH_MNT
> > >  
> > >  blocks=10
> > > -blksz=$(_get_page_size)
> > > +
> > > +# If this kernel advertises huge page support, it's possible that it could be
> > > +# using large folios for the page cache writes.  It is necessary to write
> > > +# multiple folios (large or regular) to triggering the write invalidation,
> > > +# so we'll scale the test write size accordingly.
> > > +blksz=$(_get_hugepagesize)
> > 
> > Isn't _require_hugepages needed if _get_hugepagesize is used?
> 
> Nope -- if the kernel doesn't support hugepages, then _get_hugepagesize
> returns the empty string...
> 
> > Thanks,
> > Zorro
> > 
> > > +base_pagesize=$(_get_page_size)
> > > +test -z "$blksz" && blksz=${base_pagesize}
> 
> ...and this line will substitute in the base page size as the block size.

Oh yes, you catch it at here :) OK, so the whole patchset is good to me,

Reviewed-by: Zorro Lang <zlang@redhat.com>

> 
> --D
> 
> > >  filesz=$((blocks * blksz))
> > >  dirty_offset=$(( filesz - 1 ))
> > >  write_len=$(( ( (blocks - 1) * blksz) + 1 ))
> > >  
> > > +# The write invalidation that we're testing below can only occur as part of
> > > +# a single large write.  The kernel limits writes to one base page less than
> > > +# 2GiB to prevent lengthy IOs and integer overflows.  If the block size is so
> > > +# huge (e.g. 512M huge pages on arm64) that we'd exceed that, reduce the number
> > > +# of blocks to get us under the limit.
> > > +max_writesize=$((2147483647 - base_pagesize))
> > > +if ((write_len > max_writesize)); then
> > > +	blocks=$(( ( (max_writesize - 1) / blksz) + 1))
> > > +	# We need at least three blocks in the file to test invalidation
> > > +	# between writes to multiple folios.  If we drop below that,
> > > +	# reconfigure ourselves with base pages and hope for the best.
> > > +	if ((blocks < 3)); then
> > > +		blksz=$base_pagesize
> > > +		blocks=10
> > > +	fi
> > > +	filesz=$((blocks * blksz))
> > > +	dirty_offset=$(( filesz - 1 ))
> > > +	write_len=$(( ( (blocks - 1) * blksz) + 1 ))
> > > +fi
> > > +
> > >  # Create a large file with a large unwritten range.
> > >  $XFS_IO_PROG -f -c "falloc 0 $filesz" $SCRATCH_MNT/file >> $seqres.full
> > >  
> > > 
> > 
>
diff mbox series

Patch

diff --git a/tests/xfs/559 b/tests/xfs/559
index cffe5045a5..64fc16ebfd 100755
--- a/tests/xfs/559
+++ b/tests/xfs/559
@@ -42,11 +42,38 @@  $XFS_IO_PROG -c 'chattr -x' $SCRATCH_MNT &> $seqres.full
 _require_pagecache_access $SCRATCH_MNT
 
 blocks=10
-blksz=$(_get_page_size)
+
+# If this kernel advertises huge page support, it's possible that it could be
+# using large folios for the page cache writes.  It is necessary to write
+# multiple folios (large or regular) to triggering the write invalidation,
+# so we'll scale the test write size accordingly.
+blksz=$(_get_hugepagesize)
+base_pagesize=$(_get_page_size)
+test -z "$blksz" && blksz=${base_pagesize}
 filesz=$((blocks * blksz))
 dirty_offset=$(( filesz - 1 ))
 write_len=$(( ( (blocks - 1) * blksz) + 1 ))
 
+# The write invalidation that we're testing below can only occur as part of
+# a single large write.  The kernel limits writes to one base page less than
+# 2GiB to prevent lengthy IOs and integer overflows.  If the block size is so
+# huge (e.g. 512M huge pages on arm64) that we'd exceed that, reduce the number
+# of blocks to get us under the limit.
+max_writesize=$((2147483647 - base_pagesize))
+if ((write_len > max_writesize)); then
+	blocks=$(( ( (max_writesize - 1) / blksz) + 1))
+	# We need at least three blocks in the file to test invalidation
+	# between writes to multiple folios.  If we drop below that,
+	# reconfigure ourselves with base pages and hope for the best.
+	if ((blocks < 3)); then
+		blksz=$base_pagesize
+		blocks=10
+	fi
+	filesz=$((blocks * blksz))
+	dirty_offset=$(( filesz - 1 ))
+	write_len=$(( ( (blocks - 1) * blksz) + 1 ))
+fi
+
 # Create a large file with a large unwritten range.
 $XFS_IO_PROG -f -c "falloc 0 $filesz" $SCRATCH_MNT/file >> $seqres.full