From 5df65ca9c1fd472d46cc769fd3b010dc667e75aa Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Wed, 18 Sep 2024 22:20:47 +1000 Subject: [PATCH] config: remove HAVE_GET_USER_PAGES_* get_user_pages_unlocked() had stabilised by 4.9. Sponsored-by: https://despairlabs.com/sponsor/ Reviewed-by: Brian Behlendorf Reviewed-by: Tony Hutter Reviewed-by: Tino Reichardt Signed-off-by: Rob Norris Closes #16479 --- config/kernel-get-user-pages.m4 | 179 -------------------- config/kernel.m4 | 2 - include/os/linux/kernel/linux/kmap_compat.h | 45 ----- module/os/linux/zfs/zfs_uio.c | 13 +- 4 files changed, 10 insertions(+), 229 deletions(-) delete mode 100644 config/kernel-get-user-pages.m4 diff --git a/config/kernel-get-user-pages.m4 b/config/kernel-get-user-pages.m4 deleted file mode 100644 index f9d02b66a1..0000000000 --- a/config/kernel-get-user-pages.m4 +++ /dev/null @@ -1,179 +0,0 @@ -dnl # -dnl # get_user_pages_unlocked() function was not available till 4.0. -dnl # In earlier kernels (< 4.0) get_user_pages() is available(). -dnl # -dnl # 4.0 API change, -dnl # long get_user_pages_unlocked(struct task_struct *tsk, -dnl # struct mm_struct *mm, unsigned long start, unsigned long nr_pages, -dnl # int write, int force, struct page **pages) -dnl # -dnl # 4.8 API change, -dnl # long get_user_pages_unlocked(unsigned long start, -dnl # unsigned long nr_pages, int write, int force, struct page **page) -dnl # -dnl # 4.9 API change, -dnl # long get_user_pages_unlocked(usigned long start, int nr_pages, -dnl # struct page **pages, unsigned int gup_flags) -dnl # - -dnl# -dnl# Check available get_user_pages/_unlocked interfaces. -dnl# -AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_USER_PAGES], [ - ZFS_LINUX_TEST_SRC([get_user_pages_unlocked_gup_flags], [ - #include - ], [ - unsigned long start = 0; - unsigned long nr_pages = 1; - unsigned int gup_flags = 0; - struct page **pages = NULL; - long ret __attribute__ ((unused)); - - ret = get_user_pages_unlocked(start, nr_pages, pages, - gup_flags); - ]) - - ZFS_LINUX_TEST_SRC([get_user_pages_unlocked_write_flag], [ - #include - ], [ - unsigned long start = 0; - unsigned long nr_pages = 1; - int write = 0; - int force = 0; - long ret __attribute__ ((unused)); - struct page **pages = NULL; - - ret = get_user_pages_unlocked(start, nr_pages, write, force, - pages); - ]) - - ZFS_LINUX_TEST_SRC([get_user_pages_unlocked_task_struct], [ - #include - ], [ - struct task_struct *tsk = NULL; - struct mm_struct *mm = NULL; - unsigned long start = 0; - unsigned long nr_pages = 1; - int write = 0; - int force = 0; - struct page **pages = NULL; - long ret __attribute__ ((unused)); - - ret = get_user_pages_unlocked(tsk, mm, start, nr_pages, write, - force, pages); - ]) - - ZFS_LINUX_TEST_SRC([get_user_pages_unlocked_task_struct_gup_flags], [ - #include - ], [ - struct task_struct *tsk = NULL; - struct mm_struct *mm = NULL; - unsigned long start = 0; - unsigned long nr_pages = 1; - struct page **pages = NULL; - unsigned int gup_flags = 0; - long ret __attribute__ ((unused)); - - ret = get_user_pages_unlocked(tsk, mm, start, nr_pages, - pages, gup_flags); - ]) - - ZFS_LINUX_TEST_SRC([get_user_pages_task_struct], [ - #include - ], [ - struct task_struct *tsk = NULL; - struct mm_struct *mm = NULL; - struct vm_area_struct **vmas = NULL; - unsigned long start = 0; - unsigned long nr_pages = 1; - int write = 0; - int force = 0; - struct page **pages = NULL; - int ret __attribute__ ((unused)); - - ret = get_user_pages(tsk, mm, start, nr_pages, write, - force, pages, vmas); - ]) -]) - -dnl # -dnl # Supported get_user_pages/_unlocked interfaces checked newest to oldest. -dnl # We first check for get_user_pages_unlocked as that is available in -dnl # newer kernels. -dnl # -AC_DEFUN([ZFS_AC_KERNEL_GET_USER_PAGES], [ - dnl # - dnl # Current API (as of 4.9) of get_user_pages_unlocked - dnl # - AC_MSG_CHECKING([whether get_user_pages_unlocked() takes gup flags]) - ZFS_LINUX_TEST_RESULT([get_user_pages_unlocked_gup_flags], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_GET_USER_PAGES_UNLOCKED_GUP_FLAGS, 1, - [get_user_pages_unlocked() takes gup flags]) - ], [ - AC_MSG_RESULT(no) - - dnl # - dnl # 4.8 API change, get_user_pages_unlocked - dnl # - AC_MSG_CHECKING( - [whether get_user_pages_unlocked() takes write flag]) - ZFS_LINUX_TEST_RESULT([get_user_pages_unlocked_write_flag], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_GET_USER_PAGES_UNLOCKED_WRITE_FLAG, 1, - [get_user_pages_unlocked() takes write flag]) - ], [ - AC_MSG_RESULT(no) - - dnl # - dnl # 4.0-4.3, 4.5-4.7 API, get_user_pages_unlocked - dnl # - AC_MSG_CHECKING( - [whether get_user_pages_unlocked() takes task_struct]) - ZFS_LINUX_TEST_RESULT( - [get_user_pages_unlocked_task_struct], [ - AC_MSG_RESULT(yes) - AC_DEFINE( - HAVE_GET_USER_PAGES_UNLOCKED_TASK_STRUCT, 1, - [get_user_pages_unlocked() takes task_struct]) - ], [ - AC_MSG_RESULT(no) - - dnl # - dnl # 4.4 API, get_user_pages_unlocked - dnl # - AC_MSG_CHECKING( - [whether get_user_pages_unlocked() takes task_struct, gup_flags]) - ZFS_LINUX_TEST_RESULT( - [get_user_pages_unlocked_task_struct_gup_flags], [ - AC_MSG_RESULT(yes) - AC_DEFINE( - HAVE_GET_USER_PAGES_UNLOCKED_TASK_STRUCT_GUP_FLAGS, 1, - [get_user_pages_unlocked() takes task_struct, gup_flags]) - ], [ - AC_MSG_RESULT(no) - - dnl # - dnl # get_user_pages - dnl # - AC_MSG_CHECKING( - [whether get_user_pages() takes struct task_struct]) - ZFS_LINUX_TEST_RESULT( - [get_user_pages_task_struct], [ - AC_MSG_RESULT(yes) - AC_DEFINE( - HAVE_GET_USER_PAGES_TASK_STRUCT, 1, - [get_user_pages() takes task_struct]) - ], [ - dnl # - dnl # If we cannot map the user's - dnl # pages in then we cannot do - dnl # Direct I/O - dnl # - ZFS_LINUX_TEST_ERROR([Direct I/O]) - ]) - ]) - ]) - ]) - ]) -]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 7608f0a443..465f69b72b 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -78,7 +78,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS - ZFS_AC_KERNEL_SRC_GET_USER_PAGES ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO ZFS_AC_KERNEL_SRC_VFS_READPAGES ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS @@ -187,7 +186,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO ZFS_AC_KERNEL_VFS_READ_FOLIO ZFS_AC_KERNEL_VFS_FSYNC_2ARGS - ZFS_AC_KERNEL_GET_USER_PAGES ZFS_AC_KERNEL_VFS_DIRECT_IO ZFS_AC_KERNEL_VFS_READPAGES ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS diff --git a/include/os/linux/kernel/linux/kmap_compat.h b/include/os/linux/kernel/linux/kmap_compat.h index 432c0e9913..8f9ddca221 100644 --- a/include/os/linux/kernel/linux/kmap_compat.h +++ b/include/os/linux/kernel/linux/kmap_compat.h @@ -48,49 +48,4 @@ #define zfs_access_ok(type, addr, size) access_ok(addr, size) #endif -/* - * read returning FOLL_WRITE is due to the fact that we are stating - * that the kernel will have write access to the user pages. So, when - * a Direct I/O read request is issued, the kernel must write to the user - * pages. - * - * get_user_pages_unlocked was not available to 4.0, so we also check - * for get_user_pages on older kernels. - */ -/* 4.9 API change - for and read flag is passed as gup flags */ -#if defined(HAVE_GET_USER_PAGES_UNLOCKED_GUP_FLAGS) -#define zfs_get_user_pages(addr, numpages, read, pages) \ - get_user_pages_unlocked(addr, numpages, pages, read ? FOLL_WRITE : 0) - -/* 4.8 API change - no longer takes struct task_struct as arguement */ -#elif defined(HAVE_GET_USER_PAGES_UNLOCKED_WRITE_FLAG) -#define zfs_get_user_pages(addr, numpages, read, pages) \ - get_user_pages_unlocked(addr, numpages, read, 0, pages) - -/* 4.0-4.3, 4.5-4.7 API */ -#elif defined(HAVE_GET_USER_PAGES_UNLOCKED_TASK_STRUCT) -#define zfs_get_user_pages(addr, numpages, read, pages) \ - get_user_pages_unlocked(current, current->mm, addr, numpages, read, 0, \ - pages) - -/* 4.4 API */ -#elif defined(HAVE_GET_USER_PAGES_UNLOCKED_TASK_STRUCT_GUP_FLAGS) -#define zfs_get_user_pages(addr, numpages, read, pages) \ - get_user_pages_unlocked(current, current->mm, addr, numpages, pages, \ - read ? FOLL_WRITE : 0) - -/* Using get_user_pages if kernel is < 4.0 */ -#elif defined(HAVE_GET_USER_PAGES_TASK_STRUCT) -#define zfs_get_user_pages(addr, numpages, read, pages) \ - get_user_pages(current, current->mm, addr, numpages, read, 0, pages, \ - NULL) -#else -/* - * This case is unreachable. We must be able to use either - * get_user_pages_unlocked() or get_user_pages() to map user pages into - * the kernel. - */ -#error "Unknown Direct I/O interface" -#endif - #endif /* _ZFS_KMAP_H */ diff --git a/module/os/linux/zfs/zfs_uio.c b/module/os/linux/zfs/zfs_uio.c index 8fac61fd31..0146d84233 100644 --- a/module/os/linux/zfs/zfs_uio.c +++ b/module/os/linux/zfs/zfs_uio.c @@ -589,9 +589,16 @@ zfs_uio_iov_step(struct iovec v, zfs_uio_rw_t rw, zfs_uio_t *uio, size_t len = v.iov_len; unsigned long n = DIV_ROUND_UP(len, PAGE_SIZE); - long res = zfs_get_user_pages( - P2ALIGN_TYPED(addr, PAGE_SIZE, unsigned long), n, rw == UIO_READ, - &uio->uio_dio.pages[uio->uio_dio.npages]); + /* + * read returning FOLL_WRITE is due to the fact that we are stating + * that the kernel will have write access to the user pages. So, when a + * Direct I/O read request is issued, the kernel must write to the user + * pages. + */ + long res = get_user_pages_unlocked( + P2ALIGN_TYPED(addr, PAGE_SIZE, unsigned long), n, + &uio->uio_dio.pages[uio->uio_dio.npages], + rw == UIO_READ ? FOLL_WRITE : 0); if (res < 0) { return (SET_ERROR(-res)); } else if (len != (res * PAGE_SIZE)) {