]> git.proxmox.com Git - zfsonlinux.git/blobdiff - zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch
revert potentially buggy zap_add change
[zfsonlinux.git] / zfs-patches / 0041-Fix-free-memory-calculation-on-v3.14.patch
diff --git a/zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch b/zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch
deleted file mode 100644 (file)
index 5c55057..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: chrisrd <chris@onthe.net.au>
-Date: Sat, 24 Feb 2018 03:50:06 +1100
-Subject: [PATCH] Fix free memory calculation on v3.14+
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Provide infrastructure to auto-configure to enum and API changes in the
-global page stats used for our free memory calculations.
-
-arc_free_memory has been broken since an API change in Linux v3.14:
-
-2016-07-28 v4.8 599d0c95 mm, vmscan: move LRU lists to node
-2016-07-28 v4.8 75ef7184 mm, vmstat: add infrastructure for per-node
-  vmstats
-
-These commits moved some of global_page_state() into
-global_node_page_state(). The API change was particularly egregious as,
-instead of breaking the old code, it silently did the wrong thing and we
-continued using global_page_state() where we should have been using
-global_node_page_state(), thus indexing into the wrong array via
-NR_SLAB_RECLAIMABLE et al.
-
-There have been further API changes along the way:
-
-2017-07-06 v4.13 385386cf mm: vmstat: move slab statistics from zone to
-  node counters
-2017-09-06 v4.14 c41f012a mm: rename global_page_state to
-  global_zone_page_state
-
-...and various (incomplete, as it turns out) attempts to accomodate
-these changes in ZoL:
-
-2017-08-24 2209e409 Linux 4.8+ compatibility fix for vm stats
-2017-09-16 787acae0 Linux 3.14 compat: IO acct, global_page_state, etc
-2017-09-19 661907e6 Linux 4.14 compat: IO acct, global_page_state, etc
-
-The config infrastructure provided here resolves these issues going back
-to the original API change in v3.14 and is robust against further Linux
-changes in this area.
-
-Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Reviewed-by: George Melikov <mail@gmelikov.ru>
-Signed-off-by: Chris Dunlop <chris@onthe.net.au>
-Closes #7170
-(cherry picked from commit 338523dd6ec641cc4d552c3f67e1becfb9e22b0a)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- include/linux/Makefile.am          |   3 +-
- scripts/Makefile.am                |   2 +
- include/linux/page_compat.h        |  78 ++++++++++++++++++++++++++
- module/zfs/arc.c                   |  23 ++------
- config/kernel-global_page_state.m4 | 109 +++++++++++++++++++++++++++++++++++++
- config/kernel-vm_node_stat.m4      |  22 --------
- config/kernel.m4                   |   2 +-
- scripts/enum-extract.pl            |  58 ++++++++++++++++++++
- 8 files changed, 256 insertions(+), 41 deletions(-)
- create mode 100644 include/linux/page_compat.h
- create mode 100644 config/kernel-global_page_state.m4
- delete mode 100644 config/kernel-vm_node_stat.m4
- create mode 100755 scripts/enum-extract.pl
-
-diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am
-index 9bb0b3493..89c2689f6 100644
---- a/include/linux/Makefile.am
-+++ b/include/linux/Makefile.am
-@@ -9,7 +9,8 @@ KERNEL_H = \
-       $(top_srcdir)/include/linux/kmap_compat.h \
-       $(top_srcdir)/include/linux/simd_x86.h \
-       $(top_srcdir)/include/linux/simd_aarch64.h \
--      $(top_srcdir)/include/linux/mod_compat.h
-+      $(top_srcdir)/include/linux/mod_compat.h \
-+      $(top_srcdir)/include/linux/page_compat.h
- USER_H =
-diff --git a/scripts/Makefile.am b/scripts/Makefile.am
-index 74b8b31a5..5a8abd135 100644
---- a/scripts/Makefile.am
-+++ b/scripts/Makefile.am
-@@ -5,6 +5,7 @@ EXTRA_DIST = dkms.mkconf dkms.postbuild kmodtool zfs2zol-patch.sed cstyle.pl
- pkgdatadir = $(datadir)/@PACKAGE@
- dist_pkgdata_SCRIPTS = \
-       $(top_builddir)/scripts/common.sh \
-+      $(top_srcdir)/scripts/enum-extract.pl \
-       $(top_srcdir)/scripts/zimport.sh \
-       $(top_srcdir)/scripts/zfs.sh \
-       $(top_srcdir)/scripts/zfs-tests.sh \
-@@ -15,3 +16,4 @@ dist_pkgdata_SCRIPTS = \
-       $(top_srcdir)/scripts/zpios-survey.sh \
-       $(top_srcdir)/scripts/smb.sh \
-       $(top_srcdir)/scripts/zfs-helpers.sh
-+
-diff --git a/include/linux/page_compat.h b/include/linux/page_compat.h
-new file mode 100644
-index 000000000..95acb7d53
---- /dev/null
-+++ b/include/linux/page_compat.h
-@@ -0,0 +1,78 @@
-+#ifndef       _ZFS_PAGE_COMPAT_H
-+#define       _ZFS_PAGE_COMPAT_H
-+
-+/*
-+ * We have various enum members moving between two separate enum types,
-+ * and accessed by different functions at various times. Centralise the
-+ * insanity.
-+ *
-+ * < v4.8: all enums in zone_stat_item, via global_page_state()
-+ * v4.8: some enums moved to node_stat_item, global_node_page_state() introduced
-+ * v4.13: some enums moved from zone_stat_item to node_state_item
-+ * v4.14: global_page_state() rename to global_zone_page_state()
-+ *
-+ * The defines used here are created by config/kernel-global_page_state.m4
-+ */
-+
-+/*
-+ * Create our own accessor functions to follow the Linux API changes
-+ */
-+#if   defined(ZFS_GLOBAL_ZONE_PAGE_STATE)
-+
-+/* global_zone_page_state() introduced */
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_FILE_PAGES)
-+#define       nr_file_pages() global_node_page_state(NR_FILE_PAGES)
-+#else
-+#define       nr_file_pages() global_zone_page_state(NR_FILE_PAGES)
-+#endif
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_ANON)
-+#define       nr_inactive_anon_pages() global_node_page_state(NR_INACTIVE_ANON)
-+#else
-+#define       nr_inactive_anon_pages() global_zone_page_state(NR_INACTIVE_ANON)
-+#endif
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_FILE)
-+#define       nr_inactive_file_pages() global_node_page_state(NR_INACTIVE_FILE)
-+#else
-+#define       nr_inactive_file_pages() global_zone_page_state(NR_INACTIVE_FILE)
-+#endif
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE)
-+#define       nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE)
-+#else
-+#define       nr_slab_reclaimable_pages() global_zone_page_state(NR_SLAB_RECLAIMABLE)
-+#endif
-+
-+#elif defined(ZFS_GLOBAL_NODE_PAGE_STATE)
-+
-+/* global_node_page_state() introduced */
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_FILE_PAGES)
-+#define       nr_file_pages() global_node_page_state(NR_FILE_PAGES)
-+#else
-+#define       nr_file_pages() global_page_state(NR_FILE_PAGES)
-+#endif
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_ANON)
-+#define       nr_inactive_anon_pages() global_node_page_state(NR_INACTIVE_ANON)
-+#else
-+#define       nr_inactive_anon_pages() global_page_state(NR_INACTIVE_ANON)
-+#endif
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_FILE)
-+#define       nr_inactive_file_pages() global_node_page_state(NR_INACTIVE_FILE)
-+#else
-+#define       nr_inactive_file_pages() global_page_state(NR_INACTIVE_FILE)
-+#endif
-+#if   defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE)
-+#define       nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE)
-+#else
-+#define       nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE)
-+#endif
-+
-+#else
-+
-+/* global_page_state() only */
-+#define       nr_file_pages()                 global_page_state(NR_FILE_PAGES)
-+#define       nr_inactive_anon_pages()        global_page_state(NR_INACTIVE_ANON)
-+#define       nr_inactive_file_pages()        global_page_state(NR_INACTIVE_FILE)
-+#define       nr_slab_reclaimable_pages()     global_page_state(NR_SLAB_RECLAIMABLE)
-+
-+#endif /* ZFS_GLOBAL_ZONE_PAGE_STATE */
-+
-+#endif /* _ZFS_PAGE_COMPAT_H */
-diff --git a/module/zfs/arc.c b/module/zfs/arc.c
-index 9d1d0db1d..236794672 100644
---- a/module/zfs/arc.c
-+++ b/module/zfs/arc.c
-@@ -280,6 +280,7 @@
- #include <sys/fs/swapnode.h>
- #include <sys/zpl.h>
- #include <linux/mm_compat.h>
-+#include <linux/page_compat.h>
- #endif
- #include <sys/callb.h>
- #include <sys/kstat.h>
-@@ -4016,17 +4017,11 @@ arc_free_memory(void)
-       si_meminfo(&si);
-       return (ptob(si.freeram - si.freehigh));
- #else
--#ifdef ZFS_GLOBAL_NODE_PAGE_STATE
-       return (ptob(nr_free_pages() +
--          global_node_page_state(NR_INACTIVE_FILE) +
--          global_node_page_state(NR_INACTIVE_ANON) +
--          global_node_page_state(NR_SLAB_RECLAIMABLE)));
--#else
--      return (ptob(nr_free_pages() +
--          global_page_state(NR_INACTIVE_FILE) +
--          global_page_state(NR_INACTIVE_ANON) +
--          global_page_state(NR_SLAB_RECLAIMABLE)));
--#endif /* ZFS_GLOBAL_NODE_PAGE_STATE */
-+          nr_inactive_file_pages() +
-+          nr_inactive_anon_pages() +
-+          nr_slab_reclaimable_pages()));
-+
- #endif /* CONFIG_HIGHMEM */
- #else
-       return (spa_get_random(arc_all_memory() * 20 / 100));
-@@ -4437,13 +4432,7 @@ arc_evictable_memory(void)
-        * Scale reported evictable memory in proportion to page cache, cap
-        * at specified min/max.
-        */
--#ifdef ZFS_GLOBAL_NODE_PAGE_STATE
--      uint64_t min = (ptob(global_node_page_state(NR_FILE_PAGES)) / 100) *
--          zfs_arc_pc_percent;
--#else
--      uint64_t min = (ptob(global_page_state(NR_FILE_PAGES)) / 100) *
--          zfs_arc_pc_percent;
--#endif
-+      uint64_t min = (ptob(nr_file_pages()) / 100) * zfs_arc_pc_percent;
-       min = MAX(arc_c_min, MIN(arc_c_max, min));
-       if (arc_dirty >= min)
-diff --git a/config/kernel-global_page_state.m4 b/config/kernel-global_page_state.m4
-new file mode 100644
-index 000000000..f4a40011f
---- /dev/null
-+++ b/config/kernel-global_page_state.m4
-@@ -0,0 +1,109 @@
-+dnl #
-+dnl # 4.8 API change
-+dnl #
-+dnl # 75ef71840539 mm, vmstat: add infrastructure for per-node vmstats
-+dnl # 599d0c954f91 mm, vmscan: move LRU lists to node
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE], [
-+      AC_MSG_CHECKING([whether global_node_page_state() exists])
-+      ZFS_LINUX_TRY_COMPILE([
-+              #include <linux/mm.h>
-+              #include <linux/vmstat.h>
-+      ],[
-+              (void) global_node_page_state(0);
-+      ],[
-+              AC_MSG_RESULT(yes)
-+              AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1, [global_node_page_state() exists])
-+      ],[
-+              AC_MSG_RESULT(no)
-+      ])
-+])
-+
-+dnl #
-+dnl # 4.14 API change
-+dnl #
-+dnl # c41f012ade0b mm: rename global_page_state to global_zone_page_state
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE], [
-+      AC_MSG_CHECKING([whether global_zone_page_state() exists])
-+      ZFS_LINUX_TRY_COMPILE([
-+              #include <linux/mm.h>
-+              #include <linux/vmstat.h>
-+      ],[
-+              (void) global_zone_page_state(0);
-+      ],[
-+              AC_MSG_RESULT(yes)
-+              AC_DEFINE(ZFS_GLOBAL_ZONE_PAGE_STATE, 1, [global_zone_page_state() exists])
-+      ],[
-+              AC_MSG_RESULT(no)
-+      ])
-+])
-+
-+dnl #
-+dnl # Create a define and autoconf variable for an enum member
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_ENUM_MEMBER], [
-+      AC_MSG_CHECKING([whether enum $2 contains $1])
-+      AS_IF([AC_TRY_COMMAND("${srcdir}/scripts/enum-extract.pl" "$2" "$3" | egrep -qx $1)],[
-+              AC_MSG_RESULT([yes])
-+              AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1, [enum $2 contains $1])
-+              m4_join([_], [ZFS_ENUM], m4_toupper($2), $1)=1
-+      ],[
-+              AC_MSG_RESULT([no])
-+      ])
-+])
-+
-+dnl #
-+dnl # Sanity check helpers
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR],[
-+      AC_MSG_RESULT(no)
-+      AC_MSG_RESULT([$1 in either node_stat_item or zone_stat_item: $2])
-+      AC_MSG_RESULT([configure needs updating, see: config/kernel-global_page_state.m4])
-+      AC_MSG_FAILURE([SHUT 'ER DOWN CLANCY, SHE'S PUMPIN' MUD!])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK], [
-+      enum_check_a="m4_join([_], [$ZFS_ENUM_NODE_STAT_ITEM], $1)"
-+      enum_check_b="m4_join([_], [$ZFS_ENUM_ZONE_STAT_ITEM], $1)"
-+      AS_IF([test -n "$enum_check_a" -a -n "$enum_check_b"],[
-+              ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR([$1], [DUPLICATE])
-+      ])
-+      AS_IF([test -z "$enum_check_a" -a -z "$enum_check_b"],[
-+              ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR([$1], [NOT FOUND])
-+      ])
-+])
-+
-+dnl #
-+dnl # Ensure the config tests are finding one and only one of each enum of interest
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [
-+      AC_MSG_CHECKING([global_page_state enums are sane])
-+
-+      ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_FILE_PAGES])
-+      ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_ANON])
-+      ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_FILE])
-+      ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_SLAB_RECLAIMABLE])
-+
-+      AC_MSG_RESULT(yes)
-+])
-+
-+dnl #
-+dnl # enum members in which we're interested
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [
-+      ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE
-+      ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE
-+
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],              [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON],           [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],           [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],        [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],              [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON],           [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],           [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+      ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],        [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+
-+      ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY
-+])
-diff --git a/config/kernel-vm_node_stat.m4 b/config/kernel-vm_node_stat.m4
-deleted file mode 100644
-index 5dcd9d827..000000000
---- a/config/kernel-vm_node_stat.m4
-+++ /dev/null
-@@ -1,22 +0,0 @@
--dnl #
--dnl # 4.8 API change
--dnl # kernel vm counters change
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_VM_NODE_STAT], [
--      AC_MSG_CHECKING([whether to use vm_node_stat based fn's])
--      ZFS_LINUX_TRY_COMPILE([
--              #include <linux/mm.h>
--              #include <linux/vmstat.h>
--      ],[
--                      int a __attribute__ ((unused)) = NR_VM_NODE_STAT_ITEMS;
--                      long x __attribute__ ((unused)) =
--                              atomic_long_read(&vm_node_stat[0]);
--                      (void) global_node_page_state(0);
--      ],[
--              AC_MSG_RESULT(yes)
--              AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1,
--                      [using global_node_page_state()])
--      ],[
--              AC_MSG_RESULT(no)
--      ])
--])
-diff --git a/config/kernel.m4 b/config/kernel.m4
-index 7bb86a96e..3e499e447 100644
---- a/config/kernel.m4
-+++ b/config/kernel.m4
-@@ -123,7 +123,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
-       ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
-       ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR
-       ZFS_AC_KERNEL_CURRENT_TIME
--      ZFS_AC_KERNEL_VM_NODE_STAT
-+      ZFS_AC_KERNEL_GLOBAL_PAGE_STATE
-       ZFS_AC_KERNEL_ACL_HAS_REFCOUNT
-       AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
-diff --git a/scripts/enum-extract.pl b/scripts/enum-extract.pl
-new file mode 100755
-index 000000000..5112cc807
---- /dev/null
-+++ b/scripts/enum-extract.pl
-@@ -0,0 +1,58 @@
-+#!/usr/bin/perl -w
-+
-+my $usage = <<EOT;
-+usage: config-enum enum [file ...]
-+
-+Returns the elements from an enum declaration.
-+
-+"Best effort": we're not building an entire C interpreter here!
-+EOT
-+
-+use warnings;
-+use strict;
-+use Getopt::Std;
-+
-+my %opts;
-+
-+if (!getopts("", \%opts) || @ARGV < 1) {
-+      print $usage;
-+      exit 2;
-+}
-+
-+my $enum = shift;
-+
-+my $in_enum = 0;
-+
-+while (<>) {
-+      # comments
-+      s/\/\*.*\*\///;
-+      if (m/\/\*/) {
-+              while ($_ .= <>) {
-+                      last if s/\/\*.*\*\///s;
-+              }
-+      }
-+
-+      # preprocessor stuff
-+      next if /^#/;
-+
-+      # find our enum
-+      $in_enum = 1 if s/^\s*enum\s+${enum}(?:\s|$)//;
-+      next unless $in_enum;
-+
-+      # remove explicit values
-+      s/\s*=[^,]+,/,/g;
-+
-+      # extract each identifier
-+      while (m/\b([a-z_][a-z0-9_]*)\b/ig) {
-+              print $1, "\n";
-+      }
-+
-+      #
-+      # don't exit: there may be multiple versions of the same enum, e.g.
-+      # inside different #ifdef blocks. Let's explicitly return all of
-+      # them and let external tooling deal with it.
-+      #
-+      $in_enum = 0 if m/}\s*;/;
-+}
-+
-+exit 0;
--- 
-2.14.2
-