From patchwork Wed Mar 28 15:39:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 892349 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 40BBs10Qf8z9s0x; Thu, 29 Mar 2018 02:39:49 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1f1DAu-000590-Sp; Wed, 28 Mar 2018 15:39:44 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1f1DAr-00057x-MO for kernel-team@lists.ubuntu.com; Wed, 28 Mar 2018 15:39:41 +0000 Received: from 1.general.cking.uk.vpn ([10.172.193.212] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1f1DAr-0007m3-D8; Wed, 28 Mar 2018 15:39:41 +0000 From: Colin King To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/2] UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) Date: Wed, 28 Mar 2018 16:39:40 +0100 Message-Id: <20180328153940.10077-3-colin.king@canonical.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180328153940.10077-1-colin.king@canonical.com> References: <20180328153940.10077-1-colin.king@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Colin Ian King 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 --- 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