[PATCH 2/2][BIONIC] UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
Colin King
colin.king at canonical.com
Wed Mar 28 10:19:25 UTC 2018
From: Colin Ian King <colin.king at canonical.com>
BugLink: https://bugs.launchpad.net/bugs/1754584
Fix mmap'd libaio read on non-prefaulted page deadlock. This is a hot fix
from ZFS upstream that ensure pages do not deadlock and replaces the original
fix as it is a far better solution.
Performing a read with the target data in a mmap'd page that is map'd into
the same blocks that are being read causes a lock on the page and a further
lock on the same page when the page is being faulted in, causing deadlock.
This is an improved fix from the original fix which ensures the pages don't
deadlock and removes the original potentially racy pre-faulting fix
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
zfs/META | 2 +-
zfs/Makefile.in | 2 +
zfs/aclocal.m4 | 1 +
zfs/config/user-libaio.m4 | 14 +++++++
zfs/config/user.m4 | 1 +
zfs/config/zfs-build.m4 | 4 +-
zfs/configure | 77 +++++++++++++++++++++++++++++++-----
zfs/include/Makefile.in | 2 +
zfs/include/linux/Makefile.in | 2 +
zfs/include/sys/Makefile.in | 2 +
zfs/include/sys/crypto/Makefile.in | 2 +
zfs/include/sys/fm/Makefile.in | 2 +
zfs/include/sys/fm/fs/Makefile.in | 2 +
zfs/include/sys/fs/Makefile.in | 2 +
zfs/include/sys/sysevent/Makefile.in | 2 +
zfs/module/zfs/zfs_vnops.c | 2 +-
zfs/zfs_config.h.in | 3 ++
17 files changed, 108 insertions(+), 14 deletions(-)
create mode 100644 zfs/config/user-libaio.m4
diff --git a/zfs/META b/zfs/META
index 67f3b42..9531bb8 100644
--- a/zfs/META
+++ b/zfs/META
@@ -2,7 +2,7 @@ Meta: 1
Name: zfs
Branch: 1.0
Version: 0.7.5
-Release: 1ubuntu8
+Release: 1ubuntu12
Release-Tags: relext
License: CDDL
Author: OpenZFS on Linux
diff --git a/zfs/Makefile.in b/zfs/Makefile.in
index 9dd300b..ed2c430 100644
--- a/zfs/Makefile.in
+++ b/zfs/Makefile.in
@@ -195,6 +195,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -426,6 +427,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/aclocal.m4 b/zfs/aclocal.m4
index 84d98a9..7d89c6e 100644
--- a/zfs/aclocal.m4
+++ b/zfs/aclocal.m4
@@ -1303,6 +1303,7 @@ m4_include([config/mount-helper.m4])
m4_include([config/toolchain-simd.m4])
m4_include([config/user-dracut.m4])
m4_include([config/user-frame-larger-than.m4])
+m4_include([config/user-libaio.m4])
m4_include([config/user-libattr.m4])
m4_include([config/user-libblkid.m4])
m4_include([config/user-libtirpc.m4])
diff --git a/zfs/config/user-libaio.m4 b/zfs/config/user-libaio.m4
new file mode 100644
index 0000000..d7a7cb5
--- /dev/null
+++ b/zfs/config/user-libaio.m4
@@ -0,0 +1,14 @@
+dnl #
+dnl # Check for libaio - only used for libaiot test cases.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_LIBAIO], [
+ LIBAIO=
+
+ AC_CHECK_HEADER([libaio.h], [
+ user_libaio=yes
+ AC_SUBST([LIBAIO], ["-laio"])
+ AC_DEFINE([HAVE_LIBAIO], 1, [Define if you have libaio])
+ ], [
+ user_libaio=no
+ ])
+])
diff --git a/zfs/config/user.m4 b/zfs/config/user.m4
index 2b033f5..d5d0a90 100644
--- a/zfs/config/user.m4
+++ b/zfs/config/user.m4
@@ -14,6 +14,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
ZFS_AC_CONFIG_USER_LIBBLKID
ZFS_AC_CONFIG_USER_LIBATTR
ZFS_AC_CONFIG_USER_LIBUDEV
+ ZFS_AC_CONFIG_USER_LIBAIO
ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
ZFS_AC_CONFIG_USER_RUNSTATEDIR
ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS
diff --git a/zfs/config/zfs-build.m4 b/zfs/config/zfs-build.m4
index 7651dc2..1224682 100644
--- a/zfs/config/zfs-build.m4
+++ b/zfs/config/zfs-build.m4
@@ -79,11 +79,11 @@ AC_DEFUN([ZFS_AC_CONFIG], [
AM_CONDITIONAL([CONFIG_KERNEL],
[test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all] &&
[test "x$enable_linux_builtin" != xyes ])
- AM_CONDITIONAL([WANT_DEVNAME2DEVID],
- [test "x$user_libudev" = xyes ])
AM_CONDITIONAL([CONFIG_QAT],
[test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all] &&
[test "x$qatsrc" != x ])
+ AM_CONDITIONAL([WANT_DEVNAME2DEVID], [test "x$user_libudev" = xyes ])
+ AM_CONDITIONAL([WANT_MMAP_LIBAIO], [test "x$user_libaio" = xyes ])
])
dnl #
diff --git a/zfs/configure b/zfs/configure
index aebe4bb..157b196 100755
--- a/zfs/configure
+++ b/zfs/configure
@@ -635,10 +635,12 @@ LIBOBJS
DEBUG_ZFS
DEBUG_STACKFLAGS
DEBUG_CFLAGS
-CONFIG_QAT_FALSE
-CONFIG_QAT_TRUE
+WANT_MMAP_LIBAIO_FALSE
+WANT_MMAP_LIBAIO_TRUE
WANT_DEVNAME2DEVID_FALSE
WANT_DEVNAME2DEVID_TRUE
+CONFIG_QAT_FALSE
+CONFIG_QAT_TRUE
CONFIG_KERNEL_FALSE
CONFIG_KERNEL_TRUE
CONFIG_USER_FALSE
@@ -647,6 +649,7 @@ RM
ZONENAME
NO_FORMAT_TRUNCATION
FRAME_LARGER_THAN
+LIBAIO
LIBUDEV
LIBATTR
LIBBLKID
@@ -26990,6 +26993,27 @@ fi
+ LIBAIO=
+
+ ac_fn_c_check_header_mongrel "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
+if test "x$ac_cv_header_libaio_h" = xyes; then :
+
+ user_libaio=yes
+ LIBAIO="-laio"
+
+
+$as_echo "#define HAVE_LIBAIO 1" >>confdefs.h
+
+
+else
+
+ user_libaio=no
+
+fi
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wframe-larger-than=<size> support" >&5
$as_echo_n "checking for -Wframe-larger-than=<size> support... " >&6; }
@@ -28018,6 +28042,27 @@ fi
+ LIBAIO=
+
+ ac_fn_c_check_header_mongrel "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
+if test "x$ac_cv_header_libaio_h" = xyes; then :
+
+ user_libaio=yes
+ LIBAIO="-laio"
+
+
+$as_echo "#define HAVE_LIBAIO 1" >>confdefs.h
+
+
+else
+
+ user_libaio=no
+
+fi
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wframe-larger-than=<size> support" >&5
$as_echo_n "checking for -Wframe-larger-than=<size> support... " >&6; }
@@ -40914,6 +40959,15 @@ else
CONFIG_KERNEL_FALSE=
fi
+ if test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all &&
+ test "x$qatsrc" != x ; then
+ CONFIG_QAT_TRUE=
+ CONFIG_QAT_FALSE='#'
+else
+ CONFIG_QAT_TRUE='#'
+ CONFIG_QAT_FALSE=
+fi
+
if test "x$user_libudev" = xyes ; then
WANT_DEVNAME2DEVID_TRUE=
WANT_DEVNAME2DEVID_FALSE='#'
@@ -40922,13 +40976,12 @@ else
WANT_DEVNAME2DEVID_FALSE=
fi
- if test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all &&
- test "x$qatsrc" != x ; then
- CONFIG_QAT_TRUE=
- CONFIG_QAT_FALSE='#'
+ if test "x$user_libaio" = xyes ; then
+ WANT_MMAP_LIBAIO_TRUE=
+ WANT_MMAP_LIBAIO_FALSE='#'
else
- CONFIG_QAT_TRUE='#'
- CONFIG_QAT_FALSE=
+ WANT_MMAP_LIBAIO_TRUE='#'
+ WANT_MMAP_LIBAIO_FALSE=
fi
@@ -41136,12 +41189,16 @@ if test -z "${CONFIG_KERNEL_TRUE}" && test -z "${CONFIG_KERNEL_FALSE}"; then
as_fn_error $? "conditional \"CONFIG_KERNEL\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${CONFIG_QAT_TRUE}" && test -z "${CONFIG_QAT_FALSE}"; then
+ as_fn_error $? "conditional \"CONFIG_QAT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${WANT_DEVNAME2DEVID_TRUE}" && test -z "${WANT_DEVNAME2DEVID_FALSE}"; then
as_fn_error $? "conditional \"WANT_DEVNAME2DEVID\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-if test -z "${CONFIG_QAT_TRUE}" && test -z "${CONFIG_QAT_FALSE}"; then
- as_fn_error $? "conditional \"CONFIG_QAT\" was never defined.
+if test -z "${WANT_MMAP_LIBAIO_TRUE}" && test -z "${WANT_MMAP_LIBAIO_FALSE}"; then
+ as_fn_error $? "conditional \"WANT_MMAP_LIBAIO\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
diff --git a/zfs/include/Makefile.in b/zfs/include/Makefile.in
index ae748a9..acd99dc 100644
--- a/zfs/include/Makefile.in
+++ b/zfs/include/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -400,6 +401,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/include/linux/Makefile.in b/zfs/include/linux/Makefile.in
index 0f6c8c3..1002d83 100644
--- a/zfs/include/linux/Makefile.in
+++ b/zfs/include/linux/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -345,6 +346,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/include/sys/Makefile.in b/zfs/include/sys/Makefile.in
index 25d1f71..c24010a 100644
--- a/zfs/include/sys/Makefile.in
+++ b/zfs/include/sys/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -606,6 +607,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/include/sys/crypto/Makefile.in b/zfs/include/sys/crypto/Makefile.in
index fa2f570..79a03c5 100644
--- a/zfs/include/sys/crypto/Makefile.in
+++ b/zfs/include/sys/crypto/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -342,6 +343,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/include/sys/fm/Makefile.in b/zfs/include/sys/fm/Makefile.in
index 85019a1..a73b969 100644
--- a/zfs/include/sys/fm/Makefile.in
+++ b/zfs/include/sys/fm/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -382,6 +383,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/include/sys/fm/fs/Makefile.in b/zfs/include/sys/fm/fs/Makefile.in
index 42a85e5..03e3298 100644
--- a/zfs/include/sys/fm/fs/Makefile.in
+++ b/zfs/include/sys/fm/fs/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -338,6 +339,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/include/sys/fs/Makefile.in b/zfs/include/sys/fs/Makefile.in
index d22d5fc..8ea51c9 100644
--- a/zfs/include/sys/fs/Makefile.in
+++ b/zfs/include/sys/fs/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -338,6 +339,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/include/sys/sysevent/Makefile.in b/zfs/include/sys/sysevent/Makefile.in
index 12c0912..2a9b504 100644
--- a/zfs/include/sys/sysevent/Makefile.in
+++ b/zfs/include/sys/sysevent/Makefile.in
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
$(top_srcdir)/config/toolchain-simd.m4 \
$(top_srcdir)/config/user-dracut.m4 \
$(top_srcdir)/config/user-frame-larger-than.m4 \
+ $(top_srcdir)/config/user-libaio.m4 \
$(top_srcdir)/config/user-libattr.m4 \
$(top_srcdir)/config/user-libblkid.m4 \
$(top_srcdir)/config/user-libtirpc.m4 \
@@ -342,6 +343,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBATTR = @LIBATTR@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
diff --git a/zfs/module/zfs/zfs_vnops.c b/zfs/module/zfs/zfs_vnops.c
index 6a1dab5..41eb49d 100644
--- a/zfs/module/zfs/zfs_vnops.c
+++ b/zfs/module/zfs/zfs_vnops.c
@@ -398,6 +398,7 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio)
pp = find_lock_page(mp, start >> PAGE_SHIFT);
if (pp) {
ASSERT(PageUptodate(pp));
+ unlock_page(pp);
pb = kmap(pp);
error = uiomove(pb + off, bytes, UIO_READ, uio);
@@ -407,7 +408,6 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio)
flush_dcache_page(pp);
mark_page_accessed(pp);
- unlock_page(pp);
put_page(pp);
} else {
error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
diff --git a/zfs/zfs_config.h.in b/zfs/zfs_config.h.in
index ac41b5a..a87d6ac 100644
--- a/zfs/zfs_config.h.in
+++ b/zfs/zfs_config.h.in
@@ -312,6 +312,9 @@
/* kernel has large stacks */
#undef HAVE_LARGE_STACKS
+/* Define if you have libaio */
+#undef HAVE_LIBAIO
+
/* Define if you have libattr */
#undef HAVE_LIBATTR
--
2.7.4
More information about the kernel-team
mailing list