diff options
author | Tim Chase <[email protected]> | 2015-06-14 11:19:40 -0500 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-06-17 10:43:13 -0700 |
commit | 90947b2357157a376fdd23dadbcfedad82652525 (patch) | |
tree | c8a505d82d31e31772867c95b1b2b018b2b48594 | |
parent | 410921241d00d9e6e48d6e544ab5fbf2f642a72d (diff) |
3.12 compat, NUMA-aware per-superblock shrinker
Kernels >= 3.12 have a NUMA-aware superblock shrinker which is used in
ZoL by zfs_sb_prune(). This patch calls the shrinker for each on-line
NUMA node in order that memory be freed for each one.
Signed-off-by: Tim Chase <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #3495
-rw-r--r-- | config/kernel-shrink.m4 | 22 | ||||
-rw-r--r-- | config/kernel.m4 | 1 | ||||
-rw-r--r-- | module/zfs/zfs_vfsops.c | 13 |
3 files changed, 34 insertions, 2 deletions
diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4 index 1c211ed15..a57c2afb0 100644 --- a/config/kernel-shrink.m4 +++ b/config/kernel-shrink.m4 @@ -109,3 +109,25 @@ AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [ AC_MSG_RESULT(no) ]) ]) + +dnl # +dnl # 3.12 API change +dnl # The nid member was added to struct shrink_control to support +dnl # NUMA-aware shrinkers. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [ + AC_MSG_CHECKING([whether shrink_control has nid]) + ZFS_LINUX_TRY_COMPILE([ + #include <linux/fs.h> + ],[ + struct shrink_control sc __attribute__ ((unused)); + unsigned long scnidsize __attribute__ ((unused)) = + sizeof(sc.nid); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1, + [struct shrink_control has nid]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 69470e128..a9f2f5898 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -87,6 +87,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY ZFS_AC_KERNEL_MOUNT_NODEV ZFS_AC_KERNEL_SHRINK + ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD ZFS_AC_KERNEL_S_D_OP ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 2b532a333..88f655a8c 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -68,7 +68,6 @@ #include <sys/zpl.h> #include "zfs_comutil.h" - /*ARGSUSED*/ int zfs_sync(struct super_block *sb, int wait, cred_t *cr) @@ -1093,7 +1092,17 @@ zfs_sb_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects) ZFS_ENTER(zsb); -#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) +#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \ + defined(SHRINK_CONTROL_HAS_NID) && \ + defined(SHRINKER_NUMA_AWARE) + if (sb->s_shrink.flags & SHRINKER_NUMA_AWARE) { + *objects = 0; + for_each_online_node(sc.nid) + *objects += (*shrinker->scan_objects)(shrinker, &sc); + } else { + *objects = (*shrinker->scan_objects)(shrinker, &sc); + } +#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK) *objects = (*shrinker->scan_objects)(shrinker, &sc); #elif defined(HAVE_SHRINK) *objects = (*shrinker->shrink)(shrinker, &sc); |