summary refs log tree commit diff
path: root/pkgs/os-specific/linux/spl
diff options
context:
space:
mode:
authorRicardo M. Correia <rcorreia@wizy.org>2013-11-27 02:20:34 +0100
committerRicardo M. Correia <rcorreia@wizy.org>2014-03-04 12:58:39 +0100
commit17073197e903782d32d265072326eaaf9bfe82af (patch)
treedbe495dd2929aa7cdc3fbdb95e3bd6173e945762 /pkgs/os-specific/linux/spl
parentd01242edb853b24feea936f85f33702b3c148a70 (diff)
downloadnixpkgs-17073197e903782d32d265072326eaaf9bfe82af.tar
nixpkgs-17073197e903782d32d265072326eaaf9bfe82af.tar.gz
nixpkgs-17073197e903782d32d265072326eaaf9bfe82af.tar.bz2
nixpkgs-17073197e903782d32d265072326eaaf9bfe82af.tar.lz
nixpkgs-17073197e903782d32d265072326eaaf9bfe82af.tar.xz
nixpkgs-17073197e903782d32d265072326eaaf9bfe82af.tar.zst
nixpkgs-17073197e903782d32d265072326eaaf9bfe82af.zip
spl: Fix compilation on 3.12 and later kernels
Diffstat (limited to 'pkgs/os-specific/linux/spl')
-rw-r--r--pkgs/os-specific/linux/spl/3_12-compat.patch429
-rw-r--r--pkgs/os-specific/linux/spl/default.nix2
2 files changed, 430 insertions, 1 deletions
diff --git a/pkgs/os-specific/linux/spl/3_12-compat.patch b/pkgs/os-specific/linux/spl/3_12-compat.patch
new file mode 100644
index 00000000000..b196098b7df
--- /dev/null
+++ b/pkgs/os-specific/linux/spl/3_12-compat.patch
@@ -0,0 +1,429 @@
+commit c3d9c0df3ee8d43db22815ebbfbe8b803fa46e46
+Author: Richard Yao <ryao@gentoo.org>
+Date:   Tue Nov 5 11:35:54 2013 -0500
+
+    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 <ryao@gentoo.org>
+    Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+    Closes zfsonlinux/zfs#1732
+    Closes zfsonlinux/zfs#1822
+    Closes #293
+    Closes #307
+
+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 <linux/mm.h>
+-	],[
+-		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 <linux/mm.h>
+ 
+-		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 <linux/mm.h>
++
++			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 <linux/mm.h>
++
++				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 <linux/mm.h>
++
++					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 @@ extern shrink_icache_memory_t shrink_icache_memory_fn;
+ #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 */
diff --git a/pkgs/os-specific/linux/spl/default.nix b/pkgs/os-specific/linux/spl/default.nix
index ee264f67127..9309804d007 100644
--- a/pkgs/os-specific/linux/spl/default.nix
+++ b/pkgs/os-specific/linux/spl/default.nix
@@ -7,7 +7,7 @@ stdenv.mkDerivation {
     sha256 = "196scl8q0bkkak6m0p1l1fz254cgsizqm73bf9wk3iynamq7qmrw";
   };
 
-  patches = [ ./install_prefix.patch ];
+  patches = [ ./install_prefix.patch ./3_12-compat.patch ];
 
   buildInputs = [ perl autoconf automake libtool ];