aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2009-10-30 13:53:17 -0700
committerBrian Behlendorf <[email protected]>2009-10-30 13:53:17 -0700
commit302b88e6abc3efe86411f9622b0a27a5b8b1f417 (patch)
tree1290c23f91ff930e53ab796ef6fd21fa7a0295a6
parent5e9b5d832b228b0628a61c9c1c9bf0b05d2fe122 (diff)
Add autoconf checks for atomic64_cmpxchg + atomic64_xchg
These functions didn't exist for all archs prior to 2.6.24. This patch addes an autoconf test to detect this and add them when needed. The autoconf check is needed instead of just an #ifndef because in the most modern kernels atomic64_{cmp}xchg are implemented as in inline function and not a #define.
-rw-r--r--config/spl-build.m440
-rwxr-xr-xconfigure256
-rw-r--r--include/asm/atomic_compat.h8
-rw-r--r--include/sys/atomic.h1
-rw-r--r--spl_config.h.in6
5 files changed, 311 insertions, 0 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4
index 15d10841b..9d81ccc8e 100644
--- a/config/spl-build.m4
+++ b/config/spl-build.m4
@@ -28,6 +28,8 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_ATOMIC_SPINLOCK
SPL_AC_TYPE_UINTPTR_T
SPL_AC_TYPE_ATOMIC64_T
+ SPL_AC_TYPE_ATOMIC64_CMPXCHG
+ SPL_AC_TYPE_ATOMIC64_XCHG
SPL_AC_3ARGS_INIT_WORK
SPL_AC_2ARGS_REGISTER_SYSCTL
SPL_AC_SET_SHRINKER
@@ -489,6 +491,44 @@ AC_DEFUN([SPL_AC_TYPE_ATOMIC64_T],
])
dnl #
+dnl # 2.6.24 API change,
+dnl # check if atomic64_cmpxchg is defined
+dnl #
+AC_DEFUN([SPL_AC_TYPE_ATOMIC64_CMPXCHG],
+ [AC_MSG_CHECKING([whether kernel defines atomic64_cmpxchg])
+ SPL_LINUX_TRY_COMPILE([
+ #include <asm/atomic.h>
+ ],[
+ atomic64_cmpxchg((atomic64_t *)NULL, 0, 0);
+ ],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_ATOMIC64_CMPXCHG, 1,
+ [kernel defines atomic64_cmpxchg])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+])
+
+dnl #
+dnl # 2.6.24 API change,
+dnl # check if atomic64_xchg is defined
+dnl #
+AC_DEFUN([SPL_AC_TYPE_ATOMIC64_XCHG],
+ [AC_MSG_CHECKING([whether kernel defines atomic64_xchg])
+ SPL_LINUX_TRY_COMPILE([
+ #include <asm/atomic.h>
+ ],[
+ atomic64_xchg((atomic64_t *)NULL, 0);
+ ],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_ATOMIC64_XCHG, 1,
+ [kernel defines atomic64_xchg])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+])
+
+dnl #
dnl # 2.6.20 API change,
dnl # INIT_WORK use 2 args and not store data inside
dnl #
diff --git a/configure b/configure
index bcbd0fb54..b03faa8c9 100755
--- a/configure
+++ b/configure
@@ -19356,6 +19356,134 @@ fi
+ echo "$as_me:$LINENO: checking whether kernel defines atomic64_cmpxchg" >&5
+echo $ECHO_N "checking whether kernel defines atomic64_cmpxchg... $ECHO_C" >&6
+
+
+cat >conftest.c <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #include <asm/atomic.h>
+
+int
+main (void)
+{
+
+ atomic64_cmpxchg((atomic64_t *)NULL, 0, 0);
+
+ ;
+ 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=$?
+ 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=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATOMIC64_CMPXCHG 1
+_ACEOF
+
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+
+
+fi
+
+ rm -Rf build
+
+
+
+ echo "$as_me:$LINENO: checking whether kernel defines atomic64_xchg" >&5
+echo $ECHO_N "checking whether kernel defines atomic64_xchg... $ECHO_C" >&6
+
+
+cat >conftest.c <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #include <asm/atomic.h>
+
+int
+main (void)
+{
+
+ atomic64_xchg((atomic64_t *)NULL, 0);
+
+ ;
+ 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=$?
+ 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=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATOMIC64_XCHG 1
+_ACEOF
+
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+
+
+fi
+
+ rm -Rf build
+
+
+
echo "$as_me:$LINENO: checking whether INIT_WORK wants 3 args" >&5
echo $ECHO_N "checking whether INIT_WORK wants 3 args... $ECHO_C" >&6
@@ -22527,6 +22655,134 @@ fi
+ echo "$as_me:$LINENO: checking whether kernel defines atomic64_cmpxchg" >&5
+echo $ECHO_N "checking whether kernel defines atomic64_cmpxchg... $ECHO_C" >&6
+
+
+cat >conftest.c <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #include <asm/atomic.h>
+
+int
+main (void)
+{
+
+ atomic64_cmpxchg((atomic64_t *)NULL, 0, 0);
+
+ ;
+ 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=$?
+ 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=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATOMIC64_CMPXCHG 1
+_ACEOF
+
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+
+
+fi
+
+ rm -Rf build
+
+
+
+ echo "$as_me:$LINENO: checking whether kernel defines atomic64_xchg" >&5
+echo $ECHO_N "checking whether kernel defines atomic64_xchg... $ECHO_C" >&6
+
+
+cat >conftest.c <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #include <asm/atomic.h>
+
+int
+main (void)
+{
+
+ atomic64_xchg((atomic64_t *)NULL, 0);
+
+ ;
+ 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=$?
+ 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=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATOMIC64_XCHG 1
+_ACEOF
+
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+
+
+fi
+
+ rm -Rf build
+
+
+
echo "$as_me:$LINENO: checking whether INIT_WORK wants 3 args" >&5
echo $ECHO_N "checking whether INIT_WORK wants 3 args... $ECHO_C" >&6
diff --git a/include/asm/atomic_compat.h b/include/asm/atomic_compat.h
index 2f7376925..c769d6248 100644
--- a/include/asm/atomic_compat.h
+++ b/include/asm/atomic_compat.h
@@ -55,5 +55,13 @@ static inline void atomic64_set(atomic64_t *v, __s64 i)
#endif /* HAVE_ATOMIC64_T */
+#ifndef HAVE_ATOMIC64_CMPXCHG
+#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#endif
+
+#ifndef HAVE_ATOMIC64_XCHG
+#define atomic64_xchg(v, n) (xchg(&((v)->counter), n))
+#endif
+
#endif /* _SPL_ATOMIC_COMPAT_H */
diff --git a/include/sys/atomic.h b/include/sys/atomic.h
index 4f4a1e058..7a741de17 100644
--- a/include/sys/atomic.h
+++ b/include/sys/atomic.h
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <sys/types.h>
+#include <asm/atomic_compat.h>
/*
* Two approaches to atomic operations are implemented each with its
diff --git a/spl_config.h.in b/spl_config.h.in
index feb09a865..409ee372d 100644
--- a/spl_config.h.in
+++ b/spl_config.h.in
@@ -33,9 +33,15 @@
/* device_create wants 5 args */
#undef HAVE_5ARGS_DEVICE_CREATE
+/* kernel defines atomic64_cmpxchg */
+#undef HAVE_ATOMIC64_CMPXCHG
+
/* kernel defines atomic64_t */
#undef HAVE_ATOMIC64_T
+/* kernel defines atomic64_xchg */
+#undef HAVE_ATOMIC64_XCHG
+
/* class_device_create() is available */
#undef HAVE_CLASS_DEVICE_CREATE