[PATCH 2/2][SRU][ARTFUL] UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
Colin King
colin.king at canonical.com
Wed Mar 28 15:42:52 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.
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.
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 | 2 ++
zfs/configure | 71 +++++++++++++++++++++++++++++++++++++++
zfs/include/Makefile.in | 2 ++
zfs/include/linux/Makefile.in | 2 ++
zfs/include/sys/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/module/zfs/zfs_vnops.c | 2 +-
zfs/zfs_config.h.in | 3 ++
15 files changed, 108 insertions(+), 2 deletions(-)
create mode 100644 zfs/config/user-libaio.m4
diff --git a/zfs/META b/zfs/META
index 476e914..8d835fa 100644
--- a/zfs/META
+++ b/zfs/META
@@ -2,7 +2,7 @@ Meta: 1
Name: zfs
Branch: 1.0
Version: 0.6.5.11
-Release: 1ubuntu3.2
+Release: 1ubuntu3.3
Release-Tags: relext
License: CDDL
Author: OpenZFS on Linux
diff --git a/zfs/Makefile.in b/zfs/Makefile.in
index 0793205..3089589 100644
--- a/zfs/Makefile.in
+++ b/zfs/Makefile.in
@@ -184,6 +184,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
$(top_srcdir)/config/user-arch.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-libblkid.m4 \
$(top_srcdir)/config/user-libuuid.m4 \
$(top_srcdir)/config/user-makedev.m4 \
@@ -412,6 +413,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
diff --git a/zfs/aclocal.m4 b/zfs/aclocal.m4
index 4be3696..a27355f 100644
--- a/zfs/aclocal.m4
+++ b/zfs/aclocal.m4
@@ -1292,6 +1292,7 @@ m4_include([config/mount-helper.m4])
m4_include([config/user-arch.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-libblkid.m4])
m4_include([config/user-libuuid.m4])
m4_include([config/user-makedev.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 8732393..29c81cd 100644
--- a/zfs/config/user.m4
+++ b/zfs/config/user.m4
@@ -5,6 +5,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
ZFS_AC_DKMS_INHIBIT
ZFS_AC_CONFIG_USER_MOUNT_HELPER
ZFS_AC_CONFIG_USER_UDEV
+ ZFS_AC_CONFIG_USER_LIBAIO
ZFS_AC_CONFIG_USER_SYSTEMD
ZFS_AC_CONFIG_USER_SYSVINIT
ZFS_AC_CONFIG_USER_DRACUT
diff --git a/zfs/config/zfs-build.m4 b/zfs/config/zfs-build.m4
index facd302..65325ce 100644
--- a/zfs/config/zfs-build.m4
+++ b/zfs/config/zfs-build.m4
@@ -103,6 +103,8 @@ 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([WANT_MMAP_LIBAIO], [test "x$user_libaio" = xyes ])
])
dnl #
diff --git a/zfs/configure b/zfs/configure
index 9634569..02ce407 100755
--- a/zfs/configure
+++ b/zfs/configure
@@ -636,6 +636,10 @@ DEBUG_DMU_TX
DEBUG_ZFS
DEBUG_STACKFLAGS
DEBUG_CFLAGS
+WANT_MMAP_LIBAIO_FALSE
+WANT_MMAP_LIBAIO_TRUE
+WANT_DEVNAME2DEVID_FALSE
+WANT_DEVNAME2DEVID_TRUE
CONFIG_KERNEL_FALSE
CONFIG_KERNEL_TRUE
CONFIG_USER_FALSE
@@ -662,6 +666,7 @@ systemdpresetdir
systemdunitdir
ZFS_MODULE_LOAD
ZFS_INIT_SYSTEMD
+LIBAIO
udevruledir
udevdir
mounthelperdir
@@ -12901,6 +12906,27 @@ fi
$as_echo "$udevdir;$udevruledir" >&6; }
+ 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
+
+
+
+
# Check whether --enable-systemd was given.
if test "${enable_systemd+set}" = set; then :
enableval=$enable_systemd;
@@ -37116,6 +37142,27 @@ fi
$as_echo "$udevdir;$udevruledir" >&6; }
+ 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
+
+
+
+
# Check whether --enable-systemd was given.
if test "${enable_systemd+set}" = set; then :
enableval=$enable_systemd;
@@ -37899,6 +37946,22 @@ else
CONFIG_KERNEL_FALSE=
fi
+ if test "x$user_libudev" = xyes ; then
+ WANT_DEVNAME2DEVID_TRUE=
+ WANT_DEVNAME2DEVID_FALSE='#'
+else
+ WANT_DEVNAME2DEVID_TRUE='#'
+ WANT_DEVNAME2DEVID_FALSE=
+fi
+
+ if test "x$user_libaio" = xyes ; then
+ WANT_MMAP_LIBAIO_TRUE=
+ WANT_MMAP_LIBAIO_FALSE='#'
+else
+ WANT_MMAP_LIBAIO_TRUE='#'
+ WANT_MMAP_LIBAIO_FALSE=
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether debugging is enabled" >&5
@@ -38120,6 +38183,14 @@ 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 "${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 "${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
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
diff --git a/zfs/include/Makefile.in b/zfs/include/Makefile.in
index bd90322..7c77b15 100644
--- a/zfs/include/Makefile.in
+++ b/zfs/include/Makefile.in
@@ -176,6 +176,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
$(top_srcdir)/config/user-arch.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-libblkid.m4 \
$(top_srcdir)/config/user-libuuid.m4 \
$(top_srcdir)/config/user-makedev.m4 \
@@ -387,6 +388,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
diff --git a/zfs/include/linux/Makefile.in b/zfs/include/linux/Makefile.in
index 9deb2b6..b774eb2 100644
--- a/zfs/include/linux/Makefile.in
+++ b/zfs/include/linux/Makefile.in
@@ -176,6 +176,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
$(top_srcdir)/config/user-arch.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-libblkid.m4 \
$(top_srcdir)/config/user-libuuid.m4 \
$(top_srcdir)/config/user-makedev.m4 \
@@ -329,6 +330,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
diff --git a/zfs/include/sys/Makefile.in b/zfs/include/sys/Makefile.in
index 68f4a7b..eb1b7d1 100644
--- a/zfs/include/sys/Makefile.in
+++ b/zfs/include/sys/Makefile.in
@@ -176,6 +176,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
$(top_srcdir)/config/user-arch.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-libblkid.m4 \
$(top_srcdir)/config/user-libuuid.m4 \
$(top_srcdir)/config/user-makedev.m4 \
@@ -561,6 +562,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
diff --git a/zfs/include/sys/fm/Makefile.in b/zfs/include/sys/fm/Makefile.in
index aaa8bf9..8ef5437 100644
--- a/zfs/include/sys/fm/Makefile.in
+++ b/zfs/include/sys/fm/Makefile.in
@@ -176,6 +176,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
$(top_srcdir)/config/user-arch.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-libblkid.m4 \
$(top_srcdir)/config/user-libuuid.m4 \
$(top_srcdir)/config/user-makedev.m4 \
@@ -369,6 +370,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
diff --git a/zfs/include/sys/fm/fs/Makefile.in b/zfs/include/sys/fm/fs/Makefile.in
index a0a9a7e..e1277f7 100644
--- a/zfs/include/sys/fm/fs/Makefile.in
+++ b/zfs/include/sys/fm/fs/Makefile.in
@@ -176,6 +176,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
$(top_srcdir)/config/user-arch.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-libblkid.m4 \
$(top_srcdir)/config/user-libuuid.m4 \
$(top_srcdir)/config/user-makedev.m4 \
@@ -325,6 +326,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
diff --git a/zfs/include/sys/fs/Makefile.in b/zfs/include/sys/fs/Makefile.in
index c556d05..1016d24 100644
--- a/zfs/include/sys/fs/Makefile.in
+++ b/zfs/include/sys/fs/Makefile.in
@@ -176,6 +176,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
$(top_srcdir)/config/user-arch.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-libblkid.m4 \
$(top_srcdir)/config/user-libuuid.m4 \
$(top_srcdir)/config/user-makedev.m4 \
@@ -325,6 +326,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
LIBBLKID = @LIBBLKID@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
diff --git a/zfs/module/zfs/zfs_vnops.c b/zfs/module/zfs/zfs_vnops.c
index 437a63a..2a5b76d 100644
--- a/zfs/module/zfs/zfs_vnops.c
+++ b/zfs/module/zfs/zfs_vnops.c
@@ -391,6 +391,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);
@@ -400,7 +401,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 94bbeb9..679f31a 100644
--- a/zfs/zfs_config.h.in
+++ b/zfs/zfs_config.h.in
@@ -258,6 +258,9 @@
/* kernel has large stacks */
#undef HAVE_LARGE_STACKS
+/* Define if you have libaio */
+#undef HAVE_LIBAIO
+
/* Define if you have libblkid */
#undef HAVE_LIBBLKID
--
2.7.4
More information about the kernel-team
mailing list