diff --git a/config/kernel-kmap-local-page.m4 b/config/kernel-kmap-local-page.m4 new file mode 100644 index 000000000..1990914d4 --- /dev/null +++ b/config/kernel-kmap-local-page.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # 5.11 API change +dnl # kmap_atomic() was deprecated in favor of kmap_local_page() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KMAP_LOCAL_PAGE], [ + ZFS_LINUX_TEST_SRC([kmap_local_page], [ + #include + ],[ + struct page page; + kmap_local_page(&page); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KMAP_LOCAL_PAGE], [ + AC_MSG_CHECKING([whether kmap_local_page exists]) + ZFS_LINUX_TEST_RESULT([kmap_local_page], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KMAP_LOCAL_PAGE, 1, + [kernel has kmap_local_page]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index b51477b6a..f282ccd8b 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -125,6 +125,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE ZFS_AC_KERNEL_SRC_VFS_FILE_OPERATIONS_EXTEND ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS + ZFS_AC_KERNEL_SRC_KMAP_LOCAL_PAGE ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT @@ -276,6 +277,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE ZFS_AC_KERNEL_VFS_FILE_OPERATIONS_EXTEND ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS + ZFS_AC_KERNEL_KMAP_LOCAL_PAGE ZFS_AC_KERNEL_FOLLOW_DOWN_ONE ZFS_AC_KERNEL_MAKE_REQUEST_FN ZFS_AC_KERNEL_GENERIC_IO_ACCT diff --git a/include/os/linux/kernel/linux/kmap_compat.h b/include/os/linux/kernel/linux/kmap_compat.h index 7f9c00af8..fb59c5f02 100644 --- a/include/os/linux/kernel/linux/kmap_compat.h +++ b/include/os/linux/kernel/linux/kmap_compat.h @@ -29,9 +29,15 @@ #include #include +#ifdef HAVE_KMAP_LOCAL_PAGE +/* 5.11 API change */ +#define zfs_kmap_local(page) kmap_local_page(page) +#define zfs_kunmap_local(addr) kunmap_local(addr) +#else /* 2.6.37 API change */ -#define zfs_kmap_atomic(page) kmap_atomic(page) -#define zfs_kunmap_atomic(addr) kunmap_atomic(addr) +#define zfs_kmap_local(page) kmap_atomic(page) +#define zfs_kunmap_local(addr) kunmap_atomic(addr) +#endif /* 5.0 API change - no more 'type' argument for access_ok() */ #ifdef HAVE_ACCESS_OK_TYPE diff --git a/module/os/linux/zfs/abd_os.c b/module/os/linux/zfs/abd_os.c index cee7410c8..4bf9eaf77 100644 --- a/module/os/linux/zfs/abd_os.c +++ b/module/os/linux/zfs/abd_os.c @@ -526,8 +526,8 @@ abd_alloc_zero_scatter(void) #define PAGE_SHIFT (highbit64(PAGESIZE)-1) #endif -#define zfs_kmap_atomic(chunk) ((void *)chunk) -#define zfs_kunmap_atomic(addr) do { (void)(addr); } while (0) +#define zfs_kmap_local(chunk) ((void *)chunk) +#define zfs_kunmap_local(addr) do { (void)(addr); } while (0) #define local_irq_save(flags) do { (void)(flags); } while (0) #define local_irq_restore(flags) do { (void)(flags); } while (0) #define nth_page(pg, i) \ @@ -980,7 +980,7 @@ abd_iter_map(struct abd_iter *aiter) aiter->iter_mapsize = MIN(aiter->iter_sg->length - offset, aiter->iter_abd->abd_size - aiter->iter_pos); - paddr = zfs_kmap_atomic(sg_page(aiter->iter_sg)); + paddr = zfs_kmap_local(sg_page(aiter->iter_sg)); } aiter->iter_mapaddr = (char *)paddr + offset; @@ -999,7 +999,7 @@ abd_iter_unmap(struct abd_iter *aiter) if (!abd_is_linear(aiter->iter_abd)) { /* LINTED E_FUNC_SET_NOT_USED */ - zfs_kunmap_atomic(aiter->iter_mapaddr - aiter->iter_offset); + zfs_kunmap_local(aiter->iter_mapaddr - aiter->iter_offset); } ASSERT3P(aiter->iter_mapaddr, !=, NULL); diff --git a/module/os/linux/zfs/zfs_uio.c b/module/os/linux/zfs/zfs_uio.c index c2ed67c43..a99a1ba88 100644 --- a/module/os/linux/zfs/zfs_uio.c +++ b/module/os/linux/zfs/zfs_uio.c @@ -136,7 +136,7 @@ zfs_uiomove_bvec_impl(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio) void *paddr; cnt = MIN(bv->bv_len - skip, n); - paddr = zfs_kmap_atomic(bv->bv_page); + paddr = zfs_kmap_local(bv->bv_page); if (rw == UIO_READ) { /* Copy from buffer 'p' to the bvec data */ memcpy(paddr + bv->bv_offset + skip, p, cnt); @@ -144,7 +144,7 @@ zfs_uiomove_bvec_impl(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio) /* Copy from bvec data to buffer 'p' */ memcpy(p, paddr + bv->bv_offset + skip, cnt); } - zfs_kunmap_atomic(paddr); + zfs_kunmap_local(paddr); skip += cnt; if (skip == bv->bv_len) { @@ -168,7 +168,7 @@ zfs_copy_bvec(void *p, size_t skip, size_t cnt, zfs_uio_rw_t rw, { void *paddr; - paddr = zfs_kmap_atomic(bv->bv_page); + paddr = zfs_kmap_local(bv->bv_page); if (rw == UIO_READ) { /* Copy from buffer 'p' to the bvec data */ memcpy(paddr + bv->bv_offset + skip, p, cnt); @@ -176,7 +176,7 @@ zfs_copy_bvec(void *p, size_t skip, size_t cnt, zfs_uio_rw_t rw, /* Copy from bvec data to buffer 'p' */ memcpy(p, paddr + bv->bv_offset + skip, cnt); } - zfs_kunmap_atomic(paddr); + zfs_kunmap_local(paddr); } /*