diff --git a/config/spl-build.m4 b/config/spl-build.m4 index dffa036556..ec7bda7765 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -27,6 +27,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_3ARGS_INIT_WORK SPL_AC_2ARGS_REGISTER_SYSCTL SPL_AC_SET_SHRINKER + SPL_AC_3ARGS_SHRINKER_CALLBACK SPL_AC_PATH_IN_NAMEIDATA SPL_AC_TASK_CURR SPL_AC_CTL_UNNUMBERED @@ -761,6 +762,34 @@ AC_DEFUN([SPL_AC_SET_SHRINKER], [ ]) ]) +dnl # +dnl # 2.6.35 API change, +dnl # Add context to shrinker callback +dnl # +AC_DEFUN([SPL_AC_3ARGS_SHRINKER_CALLBACK], + [AC_MSG_CHECKING([whether shrinker callback wants 3 args]) + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + SPL_LINUX_TRY_COMPILE([ + #include + + int shrinker_cb(struct shrinker *, int, unsigned int); + ],[ + struct shrinker cache_shrinker = { + .shrink = shrinker_cb, + .seeks = DEFAULT_SEEKS, + }; + register_shrinker(&cache_shrinker); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1, + [shrinker callback wants 3 args]) + ],[ + AC_MSG_RESULT(no) + ]) + EXTRA_KCFLAGS="$tmp_flags" +]) + dnl # dnl # 2.6.25 API change, dnl # struct path entry added to struct nameidata diff --git a/configure b/configure index 5784ec75c0..1a3b376886 100755 --- a/configure +++ b/configure @@ -12380,6 +12380,79 @@ fi + { $as_echo "$as_me:$LINENO: checking whether shrinker callback wants 3 args" >&5 +$as_echo_n "checking whether shrinker callback wants 3 args... " >&6; } + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + + int shrinker_cb(struct shrinker *, int, unsigned int); + +int +main (void) +{ + + struct shrinker cache_shrinker = { + .shrink = shrinker_cb, + .seeks = DEFAULT_SEEKS, + }; + register_shrinker(&cache_shrinker); + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_3ARGS_SHRINKER_CALLBACK 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + EXTRA_KCFLAGS="$tmp_flags" + { $as_echo "$as_me:$LINENO: checking whether struct path used in struct nameidata" >&5 $as_echo_n "checking whether struct path used in struct nameidata... " >&6; } @@ -15929,6 +16002,79 @@ fi + { $as_echo "$as_me:$LINENO: checking whether shrinker callback wants 3 args" >&5 +$as_echo_n "checking whether shrinker callback wants 3 args... " >&6; } + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + + int shrinker_cb(struct shrinker *, int, unsigned int); + +int +main (void) +{ + + struct shrinker cache_shrinker = { + .shrink = shrinker_cb, + .seeks = DEFAULT_SEEKS, + }; + register_shrinker(&cache_shrinker); + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_3ARGS_SHRINKER_CALLBACK 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + EXTRA_KCFLAGS="$tmp_flags" + { $as_echo "$as_me:$LINENO: checking whether struct path used in struct nameidata" >&5 $as_echo_n "checking whether struct path used in struct nameidata... " >&6; } diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c index aefa00fa6c..1a9c1fe96f 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -817,13 +817,18 @@ static int spl_cache_flush(spl_kmem_cache_t *skc, #ifdef HAVE_SET_SHRINKER static struct shrinker *spl_kmem_cache_shrinker; #else -static int spl_kmem_cache_generic_shrinker(int nr_to_scan, - unsigned int gfp_mask); +# ifdef HAVE_3ARGS_SHRINKER_CALLBACK +static int spl_kmem_cache_generic_shrinker(struct shrinker *shrinker_cb, + int nr_to_scan, unsigned int gfp_mask); +# else +static int spl_kmem_cache_generic_shrinker( + int nr_to_scan, unsigned int gfp_mask); +# endif /* HAVE_3ARGS_SHRINKER_CALLBACK */ static struct shrinker spl_kmem_cache_shrinker = { .shrink = spl_kmem_cache_generic_shrinker, .seeks = KMC_DEFAULT_SEEKS, }; -#endif +#endif /* HAVE_SET_SHRINKER */ static void * kv_alloc(spl_kmem_cache_t *skc, int size, int flags) @@ -1829,8 +1834,14 @@ EXPORT_SYMBOL(spl_kmem_cache_free); * objects should be freed, because Solaris semantics are to free * all available objects we may free more objects than requested. */ +#ifdef HAVE_3ARGS_SHRINKER_CALLBACK +static int +spl_kmem_cache_generic_shrinker(struct shrinker *shrinker_cb, + int nr_to_scan, unsigned int gfp_mask) +#else static int spl_kmem_cache_generic_shrinker(int nr_to_scan, unsigned int gfp_mask) +#endif /* HAVE_3ARGS_SHRINKER_CALLBACK */ { spl_kmem_cache_t *skc; int unused = 0; @@ -1894,7 +1905,11 @@ EXPORT_SYMBOL(spl_kmem_cache_reap_now); void spl_kmem_reap(void) { +#ifdef HAVE_3ARGS_SHRINKER_CALLBACK + spl_kmem_cache_generic_shrinker(NULL, KMC_REAP_CHUNK, GFP_KERNEL); +#else spl_kmem_cache_generic_shrinker(KMC_REAP_CHUNK, GFP_KERNEL); +#endif /* HAVE_3ARGS_SHRINKER_CALLBACK */ } EXPORT_SYMBOL(spl_kmem_reap); diff --git a/spl_config.h.in b/spl_config.h.in index d3928f4ba9..2a08694c90 100644 --- a/spl_config.h.in +++ b/spl_config.h.in @@ -27,6 +27,9 @@ /* on_each_cpu wants 3 args */ #undef HAVE_3ARGS_ON_EACH_CPU +/* shrinker callback wants 3 args */ +#undef HAVE_3ARGS_SHRINKER_CALLBACK + /* vfs_rename() wants 4 args */ #undef HAVE_4ARGS_VFS_RENAME