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 + ],[ + 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 #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);