From: Colin Ian King Date: Wed, 28 Mar 2018 15:42:00 +0000 (+0200) Subject: UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) X-Git-Tag: Ubuntu-4.13.0-39.44~23 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=3f5d8d55629630dafe8b9d0e6c27cf0cc4941153;p=mirror_ubuntu-artful-kernel.git UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) 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 Acked-by: Stefan Bader Acked-by: Kleber Sacilotto de Souza Signed-off-by: Kleber Sacilotto de Souza --- diff --git a/zfs/META b/zfs/META index 476e914de330..8d835fa50f8b 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 0793205bb13e..3089589768f6 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 4be369660e9c..a27355f6352f 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 000000000000..d7a7cb508df8 --- /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 87323937a589..29c81cd81e5f 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 facd30282701..65325ceae24c 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 9634569bb611..02ce40717438 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 bd90322d2ac2..7c77b15dce74 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 9deb2b6f136d..b774eb2001dd 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 68f4a7bb5330..eb1b7d1e69e8 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 aaa8bf9eed13..8ef54373a89e 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 a0a9a7e3d350..e1277f730e47 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 c556d057ceb5..1016d242d3da 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 437a63a638d1..2a5b76d79f2f 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 94bbeb9e6216..679f31a90a2d 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