From 92f2d5c0ad38cddd098fa1952202fc96a6981f54 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Wed, 11 Dec 2013 13:28:06 +0000 Subject: testing/spl-gresc: add missing patch --- testing/spl-grsec/linux-3.12.patch | 435 +++++++++++++++++++++++++++++++++++++ 1 file changed, 435 insertions(+) create mode 100644 testing/spl-grsec/linux-3.12.patch diff --git a/testing/spl-grsec/linux-3.12.patch b/testing/spl-grsec/linux-3.12.patch new file mode 100644 index 000000000..105b0dcb2 --- /dev/null +++ b/testing/spl-grsec/linux-3.12.patch @@ -0,0 +1,435 @@ +From c3d9c0df3ee8d43db22815ebbfbe8b803fa46e46 Mon Sep 17 00:00:00 2001 +From: Richard Yao +Date: Tue, 5 Nov 2013 11:35:54 -0500 +Subject: [PATCH] Linux 3.12 compat: New shrinker API + +torvalds/linux@24f7c6 introduced a new shrinker API while +torvalds/linux@a0b021 dropped support for the old shrinker API. +This patch adds support for the new shrinker API by wrapping +the old one with the new one. + +This change also reorganizes the autotools checks on the shrinker +API such that the configure script will fail early if an unknown +API is encountered in the future. + +Support for the set_shrinker() API which was used by Linux 2.6.22 +and older has been dropped. As a general rule compatibility is +only maintained back to Linux 2.6.26. + +Signed-off-by: Richard Yao +Signed-off-by: Brian Behlendorf +Closes zfsonlinux/zfs#1732 +Closes zfsonlinux/zfs#1822 +Closes #293 +Closes #307 +--- + config/spl-build.m4 | 116 ++++++++++++++++++------ + include/linux/mm_compat.h | 226 +++++++++++++++++++++++++++++----------------- + 2 files changed, 229 insertions(+), 113 deletions(-) + +diff --git a/config/spl-build.m4 b/config/spl-build.m4 +index b0e3348..7d744db 100644 +--- a/config/spl-build.m4 ++++ b/config/spl-build.m4 +@@ -27,8 +27,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ + SPL_AC_TYPE_ATOMIC64_XCHG + SPL_AC_TYPE_UINTPTR_T + SPL_AC_2ARGS_REGISTER_SYSCTL +- SPL_AC_SET_SHRINKER +- SPL_AC_3ARGS_SHRINKER_CALLBACK ++ SPL_AC_SHRINKER_CALLBACK + SPL_AC_PATH_IN_NAMEIDATA + SPL_AC_TASK_CURR + SPL_AC_CTL_UNNUMBERED +@@ -885,37 +884,18 @@ AC_DEFUN([SPL_AC_2ARGS_REGISTER_SYSCTL], + ]) + ]) + +-dnl # +-dnl # 2.6.23 API change +-dnl # Old set_shrinker API replaced with register_shrinker +-dnl # +-AC_DEFUN([SPL_AC_SET_SHRINKER], [ +- AC_MSG_CHECKING([whether set_shrinker() available]) +- SPL_LINUX_TRY_COMPILE([ +- #include +- ],[ +- return set_shrinker(DEFAULT_SEEKS, NULL); +- ],[ +- AC_MSG_RESULT([yes]) +- AC_DEFINE(HAVE_SET_SHRINKER, 1, +- [set_shrinker() available]) +- ],[ +- AC_MSG_RESULT([no]) +- ]) +-]) +- +-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]) ++AC_DEFUN([SPL_AC_SHRINKER_CALLBACK],[ + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" ++ dnl # ++ dnl # 2.6.23 to 2.6.34 API change ++ dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask) ++ dnl # ++ AC_MSG_CHECKING([whether old 2-argument shrinker exists]) + SPL_LINUX_TRY_COMPILE([ + #include + +- int shrinker_cb(struct shrinker *, int, unsigned int); ++ int shrinker_cb(int nr_to_scan, gfp_t gfp_mask); + ],[ + struct shrinker cache_shrinker = { + .shrink = shrinker_cb, +@@ -924,10 +904,86 @@ AC_DEFUN([SPL_AC_3ARGS_SHRINKER_CALLBACK], + register_shrinker(&cache_shrinker); + ],[ + AC_MSG_RESULT(yes) +- AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1, +- [shrinker callback wants 3 args]) ++ AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1, ++ [old shrinker callback wants 2 args]) + ],[ + AC_MSG_RESULT(no) ++ dnl # ++ dnl # 2.6.35 - 2.6.39 API change ++ dnl # ->shrink(struct shrinker *, ++ dnl # int nr_to_scan, gfp_t gfp_mask) ++ dnl # ++ AC_MSG_CHECKING([whether old 3-argument shrinker exists]) ++ SPL_LINUX_TRY_COMPILE([ ++ #include ++ ++ int shrinker_cb(struct shrinker *, int nr_to_scan, ++ gfp_t gfp_mask); ++ ],[ ++ 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, ++ [old shrinker callback wants 3 args]) ++ ],[ ++ AC_MSG_RESULT(no) ++ dnl # ++ dnl # 3.0 - 3.11 API change ++ dnl # ->shrink(struct shrinker *, ++ dnl # struct shrink_control *sc) ++ dnl # ++ AC_MSG_CHECKING( ++ [whether new 2-argument shrinker exists]) ++ SPL_LINUX_TRY_COMPILE([ ++ #include ++ ++ int shrinker_cb(struct shrinker *, ++ struct shrink_control *sc); ++ ],[ ++ struct shrinker cache_shrinker = { ++ .shrink = shrinker_cb, ++ .seeks = DEFAULT_SEEKS, ++ }; ++ register_shrinker(&cache_shrinker); ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1, ++ [new shrinker callback wants 2 args]) ++ ],[ ++ AC_MSG_RESULT(no) ++ dnl # ++ dnl # 3.12 API change, ++ dnl # ->shrink() is logically split in to ++ dnl # ->count_objects() and ->scan_objects() ++ dnl # ++ AC_MSG_CHECKING( ++ [whether ->count_objects callback exists]) ++ SPL_LINUX_TRY_COMPILE([ ++ #include ++ ++ unsigned long shrinker_cb( ++ struct shrinker *, ++ struct shrink_control *sc); ++ ],[ ++ struct shrinker cache_shrinker = { ++ .count_objects = shrinker_cb, ++ .scan_objects = shrinker_cb, ++ .seeks = DEFAULT_SEEKS, ++ }; ++ register_shrinker(&cache_shrinker); ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, ++ 1, [->count_objects exists]) ++ ],[ ++ AC_MSG_ERROR(error) ++ ]) ++ ]) ++ ]) + ]) + EXTRA_KCFLAGS="$tmp_flags" + ]) +diff --git a/include/linux/mm_compat.h b/include/linux/mm_compat.h +index cb1bef9..37c9b08 100644 +--- a/include/linux/mm_compat.h ++++ b/include/linux/mm_compat.h +@@ -148,107 +148,167 @@ typedef int (*shrink_icache_memory_t)(struct shrinker *, + #endif /* HAVE_SHRINK_ICACHE_MEMORY */ + + /* +- * Linux 2.6. - 2.6. Shrinker API Compatibility. ++ * Due to frequent changes in the shrinker API the following ++ * compatibility wrappers should be used. They are as follows: ++ * ++ * SPL_SHRINKER_DECLARE is used to declare the shrinker which is ++ * passed to spl_register_shrinker()/spl_unregister_shrinker(). Use ++ * shrinker_name to set the shrinker variable name, shrinker_callback ++ * to set the callback function, and seek_cost to define the cost of ++ * reclaiming an object. ++ * ++ * SPL_SHRINKER_DECLARE(shrinker_name, shrinker_callback, seek_cost); ++ * ++ * SPL_SHRINKER_CALLBACK_FWD_DECLARE is used when a forward declaration ++ * of the shrinker callback function is required. Only the callback ++ * function needs to be passed. ++ * ++ * SPL_SHRINKER_CALLBACK_FWD_DECLARE(shrinker_callback); ++ * ++ * SPL_SHRINKER_CALLBACK_WRAPPER is used to declare the callback function ++ * which is registered with the shrinker. This function will call your ++ * custom shrinker which must use the following prototype. Notice the ++ * leading __'s, these must be appended to the callback_function name. ++ * ++ * int __shrinker_callback(struct shrinker *, struct shrink_control *) ++ * SPL_SHRINKER_CALLBACK_WRAPPER(shrinker_callback);a ++ * ++ * ++ * Example: ++ * ++ * SPL_SHRINKER_CALLBACK_FWD_DECLARE(my_shrinker_fn); ++ * SPL_SHRINKER_DECLARE(my_shrinker, my_shrinker_fn, 1); ++ * ++ * static int ++ * __my_shrinker_fn(struct shrinker *shrink, struct shrink_control *sc) ++ * { ++ * if (sc->nr_to_scan) { ++ * ...scan objects in the cache and reclaim them... ++ * } ++ * ++ * ...calculate number of objects in the cache... ++ * ++ * return (number of objects in the cache); ++ * } ++ * SPL_SHRINKER_CALLBACK_WRAPPER(my_shrinker_fn); + */ +-#ifdef HAVE_SET_SHRINKER +-typedef struct spl_shrinker { +- struct shrinker *shrinker; +- shrinker_t fn; +- int seeks; +-} spl_shrinker_t; +- +-static inline void +-spl_register_shrinker(spl_shrinker_t *ss) +-{ +- ss->shrinker = set_shrinker(ss->seeks, ss->fn); +-} + +-static inline void +-spl_unregister_shrinker(spl_shrinker_t *ss) +-{ +- remove_shrinker(ss->shrinker); +-} ++#define spl_register_shrinker(x) register_shrinker(x) ++#define spl_unregister_shrinker(x) unregister_shrinker(x) + +-# define SPL_SHRINKER_DECLARE(s, x, y) \ +- static spl_shrinker_t s = { \ +- .shrinker = NULL, \ +- .fn = x, \ +- .seeks = y \ +- } +- +-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +- static int fn(int, unsigned int) +-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +-static int \ +-fn(int nr_to_scan, unsigned int gfp_mask) \ +-{ \ +- struct shrink_control sc; \ +- \ +- sc.nr_to_scan = nr_to_scan; \ +- sc.gfp_mask = gfp_mask; \ +- \ +- return __ ## fn(NULL, &sc); \ ++/* ++ * Linux 2.6.23 - 2.6.34 Shrinker API Compatibility. ++ */ ++#if defined(HAVE_2ARGS_OLD_SHRINKER_CALLBACK) ++#define SPL_SHRINKER_DECLARE(s, x, y) \ ++static struct shrinker s = { \ ++ .shrink = x, \ ++ .seeks = y \ + } + +-#else ++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ ++static int fn(int nr_to_scan, unsigned int gfp_mask) + +-# define spl_register_shrinker(x) register_shrinker(x) +-# define spl_unregister_shrinker(x) unregister_shrinker(x) +-# define SPL_SHRINKER_DECLARE(s, x, y) \ +- static struct shrinker s = { \ +- .shrink = x, \ +- .seeks = y \ +- } ++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ ++static int \ ++fn(int nr_to_scan, unsigned int gfp_mask) \ ++{ \ ++ struct shrink_control sc; \ ++ \ ++ sc.nr_to_scan = nr_to_scan; \ ++ sc.gfp_mask = gfp_mask; \ ++ \ ++ return (__ ## fn(NULL, &sc)); \ ++} + + /* +- * Linux 2.6. - 2.6. Shrinker API Compatibility. ++ * Linux 2.6.35 to 2.6.39 Shrinker API Compatibility. + */ +-# if defined(HAVE_SHRINK_CONTROL_STRUCT) +-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +- static int fn(struct shrinker *, struct shrink_control *) +-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +-static int \ +-fn(struct shrinker *shrink, struct shrink_control *sc) { \ +- return __ ## fn(shrink, sc); \ ++#elif defined(HAVE_3ARGS_SHRINKER_CALLBACK) ++#define SPL_SHRINKER_DECLARE(s, x, y) \ ++static struct shrinker s = { \ ++ .shrink = x, \ ++ .seeks = y \ ++} ++ ++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ ++static int fn(struct shrinker *, int, unsigned int) ++ ++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ ++static int \ ++fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \ ++{ \ ++ struct shrink_control sc; \ ++ \ ++ sc.nr_to_scan = nr_to_scan; \ ++ sc.gfp_mask = gfp_mask; \ ++ \ ++ return (__ ## fn(shrink, &sc)); \ + } + + /* +- * Linux 2.6. - 2.6. Shrinker API Compatibility. ++ * Linux 3.0 to 3.11 Shrinker API Compatibility. + */ +-# elif defined(HAVE_3ARGS_SHRINKER_CALLBACK) +-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +- static int fn(struct shrinker *, int, unsigned int) +-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +-static int \ +-fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \ +-{ \ +- struct shrink_control sc; \ +- \ +- sc.nr_to_scan = nr_to_scan; \ +- sc.gfp_mask = gfp_mask; \ +- \ +- return __ ## fn(shrink, &sc); \ ++#elif defined(HAVE_2ARGS_NEW_SHRINKER_CALLBACK) ++#define SPL_SHRINKER_DECLARE(s, x, y) \ ++static struct shrinker s = { \ ++ .shrink = x, \ ++ .seeks = y \ ++} ++ ++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ ++static int fn(struct shrinker *, struct shrink_control *) ++ ++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ ++static int \ ++fn(struct shrinker *shrink, struct shrink_control *sc) \ ++{ \ ++ return (__ ## fn(shrink, sc)); \ + } + + /* +- * Linux 2.6. - 2.6. Shrinker API Compatibility. ++ * Linux 3.12 and later Shrinker API Compatibility. + */ +-# else +-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +- static int fn(int, unsigned int) +-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +-static int \ +-fn(int nr_to_scan, unsigned int gfp_mask) \ +-{ \ +- struct shrink_control sc; \ +- \ +- sc.nr_to_scan = nr_to_scan; \ +- sc.gfp_mask = gfp_mask; \ +- \ +- return __ ## fn(NULL, &sc); \ ++#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK) ++#define SPL_SHRINKER_DECLARE(s, x, y) \ ++static struct shrinker s = { \ ++ .count_objects = x ## _count_objects, \ ++ .scan_objects = x ## _scan_objects, \ ++ .seeks = y \ + } + +-# endif +-#endif /* HAVE_SET_SHRINKER */ ++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ ++static unsigned long fn ## _count_objects(struct shrinker *, \ ++ struct shrink_control *); \ ++static unsigned long fn ## _scan_objects(struct shrinker *, \ ++ struct shrink_control *) ++ ++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ ++static unsigned long \ ++fn ## _count_objects(struct shrinker *shrink, struct shrink_control *sc)\ ++{ \ ++ int __ret__; \ ++ \ ++ sc->nr_to_scan = 0; \ ++ __ret__ = __ ## fn(NULL, sc); \ ++ \ ++ /* Errors may not be returned and must be converted to zeros */ \ ++ return ((__ret__ < 0) ? 0 : __ret__); \ ++} \ ++ \ ++static unsigned long \ ++fn ## _scan_objects(struct shrinker *shrink, struct shrink_control *sc) \ ++{ \ ++ int __ret__; \ ++ \ ++ __ret__ = __ ## fn(NULL, sc); \ ++ return ((__ret__ < 0) ? SHRINK_STOP : __ret__); \ ++} ++#else ++/* ++ * Linux 2.x to 2.6.22, or a newer shrinker API has been introduced. ++ */ ++#error "Unknown shrinker callback" ++#endif + + #endif /* SPL_MM_COMPAT_H */ +-- +1.8.5.1 + -- cgit v1.2.3