Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux 6.5: Replace generic_file_splice_read with filemap_splice_read #15155

Merged
merged 1 commit into from
Aug 7, 2023

Conversation

ckane
Copy link
Contributor

@ckane ckane commented Aug 5, 2023

The generic_file_splice_read function was removed in Linux 6.5 in favor of filemap_splice_read. Add an autoconf test for filemap_splice_read and use it if it is found as the handler for .splice_read in the file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This change removes the ITER_* macros that OpenZFS doesn't use from being tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was causing the test to fail, which also affected the code responsible for setting the .splice_read handler, above. That behavior caused run-time panics on Linux 6.5.

Motivation and Context

When running ZFS on 6.5rc*, a run-time panic occurs with the following stack trace:

[ 2417.825843]  ? __die+0x23/0x70
[ 2417.825974]  ? page_fault_oops+0x171/0x4e0
[ 2417.826107]  ? exc_page_fault+0x7f/0x180
[ 2417.826239]  ? asm_exc_page_fault+0x26/0x30
[ 2417.826372]  ? memcpy_orig+0x78/0x140
[ 2417.826513]  zfs_uiomove_iov+0x58/0x220 [zfs 4a5a286022a33f632f1f726c7834b01d83a9bf66]
[ 2417.826759]  dmu_read_uio_dnode+0xd3/0x150 [zfs 4a5a286022a33f632f1f726c7834b01d83a9bf66]
[ 2417.826988]  dmu_read_uio_dbuf+0x46/0x60 [zfs 4a5a286022a33f632f1f726c7834b01d83a9bf66]
[ 2417.827226]  zfs_read+0x139/0x3e0 [zfs 4a5a286022a33f632f1f726c7834b01d83a9bf66]
[ 2417.827460]  zpl_iter_read+0x116/0x1d0 [zfs 4a5a286022a33f632f1f726c7834b01d83a9bf66]
[ 2417.827689]  vfs_read+0x201/0x350
[ 2417.827839]  __x64_sys_pread64+0x98/0xd0
[ 2417.827993]  do_syscall_64+0x60/0x90
[ 2417.828154]  ? exc_page_fault+0x7f/0x180
[ 2417.828307]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8

It turns out that ITER_PIPE was removed in 6.5, and this in turn causes one of the tests setting HAVE_VFS_IOV_ITER to result in a false-negative during configure. This results in not assigning the .splice_read member of struct file_operations in module/os/linux/zfs/zpl_file.c, which was likely the cause of the memory access error above. Additionally, this struct member has been set to generic_file_splice_read up until now, but that function has also been removed in Linux 6.5. It has been superseded by filemap_splice_read. This additional regression was masked by the configure test failure due to missing ITER_PIPE.

Description

The only ITER_* macro used by OpenZFS is ITER_KVEC, so instead of trying to set an int with all possible bits set in the test, I changed it to only try setting the ITER_KVEC bit, and succeed if that works. In the future, if the remaining ones (or any future ones) are used by the code, they can be added to this test in config/kernel-vfs-iov_iter.m4. As far as I can tell, we shouldn't be failing the build if macros we don't use are removed in the kernel.

Add a new configure test for the presence of filemap_splice_read and ensure that it can be assigned to file_operations.splice_read without any type conflicts. This tests for the existence of the function, and also ensures that its type definition matches the handler in struct file_operations, the context in which we rely upon it.

Finally, add a #ifdef in the module/os/linux/zfs/zpl_file.c code that will assign file_operations.splice_read to filemap_splice_read if the latter is found by configure.

How Has This Been Tested?

Build-tested and Run-tested on Linux 6.5rc1

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Library ABI change (libzfs, libzfs_core, libnvpair, libuutil and libzfsbootenv)
  • Documentation (a change to man pages or other documentation)

Checklist:

The generic_file_splice_read function was removed in Linux 6.5 in favor
of filemap_splice_read. Add an autoconf test for filemap_splice_read and
use it if it is found as the handler for .splice_read in the
file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This
change removes the ITER_* macros that OpenZFS doesn't use from being
tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was
causing the test to fail, which also affected the code responsible for
setting the .splice_read handler, above. That behavior caused run-time
panics on Linux 6.5.

Signed-off-by: Coleman Kane <[email protected]>
@ckane ckane changed the title Replace generic_file_splice_read with filemap_splice_read Linux 6.5: Replace generic_file_splice_read with filemap_splice_read Aug 5, 2023
@ckane
Copy link
Contributor Author

ckane commented Aug 5, 2023

Alternatively, this could be written to test for generic_file_splice_read() and prefer to use it where it exists. This would minimize the behavior drift across kernels where both of these functions exist. The filemap_splice_read() was added in Feb 2023, so this probably will affect 6.4 kernels, and maybe some 6.3 kernels, as well. I'll let the CI/CD tests run and if it looks like this is causing failures on older kernels, then I'll go ahead and change the logic to favor the removed function where it is found, rather than favor its replacement.

Copy link
Contributor

@bwatkinson bwatkinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you look at the comment in zfs_uiomove_iter() in module/os/linux/zfs/zfs_uio.c about returning the value of EFAULT as it will be converted to EAGAIN by generic_file_splice_read()?

When I was looking at filemap_splice_read() I noticed it just returned the error without converting the error of EFAULT. We may need to also update this part of the code with the check to just return EAGAIN? Not sure though without spending more time looking at what error should be returned from zfs_uiomove_iter() in this case.

Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me like filemap_splice_read() will handle this correctly.

@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label Aug 7, 2023
@behlendorf behlendorf added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Aug 7, 2023
@behlendorf behlendorf merged commit 36261c8 into openzfs:master Aug 7, 2023
stgraber pushed a commit to zabbly/zfs that referenced this pull request Sep 5, 2023
…e_read

The generic_file_splice_read function was removed in Linux 6.5 in favor
of filemap_splice_read. Add an autoconf test for filemap_splice_read and
use it if it is found as the handler for .splice_read in the
file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This
change removes the ITER_* macros that OpenZFS doesn't use from being
tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was
causing the test to fail, which also affected the code responsible for
setting the .splice_read handler, above. That behavior caused run-time
panics on Linux 6.5.

Reviewed-by: Brian Atkinson <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Coleman Kane <[email protected]>
Closes openzfs#15155
stgraber pushed a commit to zabbly/zfs that referenced this pull request Sep 8, 2023
…e_read

The generic_file_splice_read function was removed in Linux 6.5 in favor
of filemap_splice_read. Add an autoconf test for filemap_splice_read and
use it if it is found as the handler for .splice_read in the
file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This
change removes the ITER_* macros that OpenZFS doesn't use from being
tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was
causing the test to fail, which also affected the code responsible for
setting the .splice_read handler, above. That behavior caused run-time
panics on Linux 6.5.

Reviewed-by: Brian Atkinson <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Coleman Kane <[email protected]>
Closes openzfs#15155
behlendorf pushed a commit that referenced this pull request Sep 19, 2023
…e_read

The generic_file_splice_read function was removed in Linux 6.5 in favor
of filemap_splice_read. Add an autoconf test for filemap_splice_read and
use it if it is found as the handler for .splice_read in the
file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This
change removes the ITER_* macros that OpenZFS doesn't use from being
tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was
causing the test to fail, which also affected the code responsible for
setting the .splice_read handler, above. That behavior caused run-time
panics on Linux 6.5.

Reviewed-by: Brian Atkinson <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Coleman Kane <[email protected]>
Closes #15155
tonyhutter pushed a commit that referenced this pull request Sep 27, 2023
…e_read

The generic_file_splice_read function was removed in Linux 6.5 in favor
of filemap_splice_read. Add an autoconf test for filemap_splice_read and
use it if it is found as the handler for .splice_read in the
file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This
change removes the ITER_* macros that OpenZFS doesn't use from being
tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was
causing the test to fail, which also affected the code responsible for
setting the .splice_read handler, above. That behavior caused run-time
panics on Linux 6.5.

Reviewed-by: Brian Atkinson <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Coleman Kane <[email protected]>
Closes #15155
lundman pushed a commit to openzfsonwindows/openzfs that referenced this pull request Dec 12, 2023
…e_read

The generic_file_splice_read function was removed in Linux 6.5 in favor
of filemap_splice_read. Add an autoconf test for filemap_splice_read and
use it if it is found as the handler for .splice_read in the
file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This
change removes the ITER_* macros that OpenZFS doesn't use from being
tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was
causing the test to fail, which also affected the code responsible for
setting the .splice_read handler, above. That behavior caused run-time
panics on Linux 6.5.

Reviewed-by: Brian Atkinson <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Coleman Kane <[email protected]>
Closes openzfs#15155
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants