about summary refs log tree commit diff
path: root/pkgs/os-specific/linux/zfs/gcc-4.8.patch
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/os-specific/linux/zfs/gcc-4.8.patch')
-rw-r--r--pkgs/os-specific/linux/zfs/gcc-4.8.patch114
1 files changed, 114 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/zfs/gcc-4.8.patch b/pkgs/os-specific/linux/zfs/gcc-4.8.patch
new file mode 100644
index 000000000000..341360163761
--- /dev/null
+++ b/pkgs/os-specific/linux/zfs/gcc-4.8.patch
@@ -0,0 +1,114 @@
+commit 0f62f3f9abc4bfa0bcafee9bfa3d55e91dcb371d
+Author: Brian Behlendorf <behlendorf1@llnl.gov>
+Date:   Tue Jan 14 09:39:13 2014 -0800
+
+    Disable GCCs aggressive loop optimization
+    
+    GCC >+ 4.8's aggressive loop optimization breaks some of the iterators
+    over the dn_blkptr[] pseudo-array in dnode_phys. Since dn_blkptr[] is
+    defined as a single-element array, GCC believes an iterator can only
+    access index 0 and will unroll the loop into a single iteration.
+    
+    One way to resolve the issue would be to cast the array to a pointer
+    and fix all the iterators that might break.  The only loop where it
+    is known to cause a problem is this loop in dmu_objset_write_ready():
+    
+        for (i = 0; i < dnp->dn_nblkptr; i++)
+                bp->blk_fill += dnp->dn_blkptr[i].blk_fill;
+    
+    In the common case where dn_nblkptr is 3, the loop is only executed a
+    single time and "i" is equal to 1 following the loop.
+    
+    The specific breakage caused by this problem is that the blk_fill of
+    root block pointers wouldn't be set properly when more than one blkptr
+    is in use (when no indrect blocks are needed).
+    
+    The simple reproducing sequence is:
+    
+    zpool create tank /tank.img
+    zdb -ddddd tank 0
+    
+    Notice that "fill=31", however, there are two L0 indirect blocks with
+    "F=31" and "F=5". The fill count should be 36 rather than 31. This
+    problem causes an assert to be hit in a simple "zdb tank" when built
+    with --enable-debug.
+    
+    However, this approach was not taken because we need to be absolutely
+    sure we catch all instances of this unwanted optimization.  Therefore,
+    the build system has been updated to detect if GCC supports the
+    aggressive loop optimization.  If it does the optimization will be
+    explicitly disabled using the -fno-aggressive-loop-optimization option.
+    
+    Original-fix-by: Tim Chase <tim@chase2k.com>
+    Signed-off-by: Tim Chase <tim@chase2k.com>
+    Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+    Closes #2010
+    Closes #2051
+
+diff --git a/config/Rules.am b/config/Rules.am
+index e3fa5b5..24f9426 100644
+--- a/config/Rules.am
++++ b/config/Rules.am
+@@ -1,8 +1,10 @@
+ DEFAULT_INCLUDES = -include ${top_builddir}/zfs_config.h
+ 
+ AM_LIBTOOLFLAGS = --silent
+-AM_CFLAGS  = -Wall -Wstrict-prototypes
+-AM_CFLAGS += -fno-strict-aliasing ${NO_UNUSED_BUT_SET_VARIABLE} ${DEBUG_CFLAGS}
++AM_CFLAGS  = ${DEBUG_CFLAGS} -Wall -Wstrict-prototypes
++AM_CFLAGS += ${NO_UNUSED_BUT_SET_VARIABLE}
++AM_CFLAGS += ${NO_AGGRESSIVE_LOOP_OPTIMIZATIONS}
++AM_CFLAGS += -fno-strict-aliasing
+ AM_CPPFLAGS  = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT
+ AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64
+ AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\"
+diff --git a/config/always-no-aggressive-loop-optimizations.m4 b/config/always-no-aggressive-loop-optimizations.m4
+new file mode 100644
+index 0000000..8f2115a
+--- /dev/null
++++ b/config/always-no-aggressive-loop-optimizations.m4
+@@ -0,0 +1,20 @@
++dnl #
++dnl # Check if gcc supports -fno-aggressive-loop-optimizations
++dnl #
++AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_NO_AGGRESSIVE_LOOP_OPTIMIZATIONS], [
++	AC_MSG_CHECKING([for -fno-aggressive-loop-optimizations support])
++
++	saved_flags="$CFLAGS"
++	CFLAGS="$CFLAGS -fno-aggressive-loop-optimizations"
++
++	AC_RUN_IFELSE([AC_LANG_PROGRAM([], [])], [
++		NO_AGGRESSIVE_LOOP_OPTIMIZATIONS=-fno-aggressive-loop-optimizations
++		AC_MSG_RESULT([yes])
++	], [
++		NO_AGGRESSIVE_LOOP_OPTIMIZATIONS=
++		AC_MSG_RESULT([no])
++	])
++
++	CFLAGS="$saved_flags"
++	AC_SUBST([NO_AGGRESSIVE_LOOP_OPTIMIZATIONS])
++])
+diff --git a/config/kernel.m4 b/config/kernel.m4
+index cbf0ca3..62a9b42 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -104,6 +104,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
+ 	dnl # -Wall -fno-strict-aliasing -Wstrict-prototypes and other
+ 	dnl # compiler options are added by the kernel build system.
+ 	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_UNUSED_BUT_SET_VARIABLE"
++	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_AGGRESSIVE_LOOP_OPTIMIZATIONS"
+ 	KERNELCPPFLAGS="$KERNELCPPFLAGS -DHAVE_SPL -D_KERNEL"
+ 	KERNELCPPFLAGS="$KERNELCPPFLAGS -DTEXT_DOMAIN=\\\"zfs-linux-kernel\\\""
+ 
+diff --git a/config/zfs-build.m4 b/config/zfs-build.m4
+index 005185b..477b916 100644
+--- a/config/zfs-build.m4
++++ b/config/zfs-build.m4
+@@ -62,6 +62,7 @@ AC_DEFUN([ZFS_AC_DEBUG_DMU_TX], [
+ 
+ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
+ 	ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE
++	ZFS_AC_CONFIG_ALWAYS_NO_AGGRESSIVE_LOOP_OPTIMIZATIONS
+ ])
+ 
+ AC_DEFUN([ZFS_AC_CONFIG], [