Atomic64 compatibility for 32-bit systems without kernel support.

This patch is another step towards updating the code to handle the
32-bit kernels which I have not been regularly testing.  This changes
do not really impact the common case I'm expected which is the latest
kernel running on an x86_64 arch.

Until the linux-2.6.31 kernel the x86 arch did not have support for
64-bit atomic operations.  Additionally, the new atomic_compat.h support
for this case was wrong because it embedded a spinlock in the atomic
variable which must always and only be 64-bits total.  To handle these
32-bit issues we now simply fall back to the --enable-atomic-spinlock
implementation if the kernel does not provide the 64-bit atomic funcs.

The second issue this patch addresses is the DEBUG_KMEM assumption that
there will always be atomic64 funcs available.  On 32-bit archs this may
not be true, and actually that's just fine.  In that case the kernel will
will never be able to allocate more the 32-bits worth anyway.  So just
check if atomic64 funcs are available, if they are not it means this
is a 32-bit machine and we can safely use atomic_t's instead.
This commit is contained in:
Brian Behlendorf
2009-12-04 15:54:12 -08:00
parent db1aa22297
commit d04c8a563c
10 changed files with 396 additions and 788 deletions
Vendored
+235 -171
View File
@@ -1039,7 +1039,7 @@ Optional Features:
--enable-debug-kmem-tracking
Enable detailed kmem tracking [default=no]
--enable-atomic-spinlocks
Atomic types use spinlocks [default=no]
Atomic types use spinlocks [default=check]
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -19160,89 +19160,9 @@ if test "${enable_atomic_spinlocks+set}" = set; then
enableval="$enable_atomic_spinlocks"
else
enable_atomic_spinlocks=no
enable_atomic_spinlocks=check
fi;
if test "x$enable_atomic_spinlocks" = xyes; then
cat >>confdefs.h <<\_ACEOF
#define ATOMIC_SPINLOCK 1
_ACEOF
fi
echo "$as_me:$LINENO: checking whether atomic types use spinlocks" >&5
echo $ECHO_N "checking whether atomic types use spinlocks... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $enable_atomic_spinlocks" >&5
echo "${ECHO_T}$enable_atomic_spinlocks" >&6
echo "$as_me:$LINENO: checking whether kernel defines uintptr_t" >&5
echo $ECHO_N "checking whether kernel defines uintptr_t... $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 <linux/types.h>
int
main (void)
{
uintptr_t *ptr;
;
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_UINTPTR_T 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_t" >&5
echo $ECHO_N "checking whether kernel defines atomic64_t... $ECHO_C" >&6
cat >conftest.c <<_ACEOF
@@ -19282,8 +19202,7 @@ _ACEOF
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
have_atomic64_t=yes
cat >>confdefs.h <<\_ACEOF
#define HAVE_ATOMIC64_T 1
@@ -19294,8 +19213,7 @@ 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
have_atomic64_t=no
@@ -19305,6 +19223,56 @@ fi
if test "x$enable_atomic_spinlocks" = xcheck; then
if test "x$have_atomic64_t" = xyes; then
enable_atomic_spinlocks=no
else
enable_atomic_spinlocks=yes
fi
fi
if test "x$enable_atomic_spinlocks" = xyes; then
cat >>confdefs.h <<\_ACEOF
#define ATOMIC_SPINLOCK 1
_ACEOF
else
if test "x$have_atomic64_t" = xno; then
{ { echo "$as_me:$LINENO: error: --disable-atomic-spinlocks given but required atomic64 support is unavailable
See \`config.log' for more details." >&5
echo "$as_me: error: --disable-atomic-spinlocks given but required atomic64 support is unavailable
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
echo "$as_me:$LINENO: checking whether atomic types use spinlocks" >&5
echo $ECHO_N "checking whether atomic types use spinlocks... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $enable_atomic_spinlocks" >&5
echo "${ECHO_T}$enable_atomic_spinlocks" >&6
echo "$as_me:$LINENO: checking whether kernel defines atomic64_t" >&5
echo $ECHO_N "checking whether kernel defines atomic64_t... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $have_atomic64_t" >&5
echo "${ECHO_T}$have_atomic64_t" >&6
echo "$as_me:$LINENO: checking whether kernel defines atomic64_cmpxchg" >&5
echo $ECHO_N "checking whether kernel defines atomic64_cmpxchg... $ECHO_C" >&6
@@ -19427,6 +19395,70 @@ echo "${ECHO_T}no" >&6
fi
rm -Rf build
echo "$as_me:$LINENO: checking whether kernel defines uintptr_t" >&5
echo $ECHO_N "checking whether kernel defines uintptr_t... $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 <linux/types.h>
int
main (void)
{
uintptr_t *ptr;
;
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_UINTPTR_T 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
@@ -22409,89 +22441,9 @@ if test "${enable_atomic_spinlocks+set}" = set; then
enableval="$enable_atomic_spinlocks"
else
enable_atomic_spinlocks=no
enable_atomic_spinlocks=check
fi;
if test "x$enable_atomic_spinlocks" = xyes; then
cat >>confdefs.h <<\_ACEOF
#define ATOMIC_SPINLOCK 1
_ACEOF
fi
echo "$as_me:$LINENO: checking whether atomic types use spinlocks" >&5
echo $ECHO_N "checking whether atomic types use spinlocks... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $enable_atomic_spinlocks" >&5
echo "${ECHO_T}$enable_atomic_spinlocks" >&6
echo "$as_me:$LINENO: checking whether kernel defines uintptr_t" >&5
echo $ECHO_N "checking whether kernel defines uintptr_t... $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 <linux/types.h>
int
main (void)
{
uintptr_t *ptr;
;
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_UINTPTR_T 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_t" >&5
echo $ECHO_N "checking whether kernel defines atomic64_t... $ECHO_C" >&6
cat >conftest.c <<_ACEOF
@@ -22531,8 +22483,7 @@ _ACEOF
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
have_atomic64_t=yes
cat >>confdefs.h <<\_ACEOF
#define HAVE_ATOMIC64_T 1
@@ -22543,8 +22494,7 @@ 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
have_atomic64_t=no
@@ -22554,6 +22504,56 @@ fi
if test "x$enable_atomic_spinlocks" = xcheck; then
if test "x$have_atomic64_t" = xyes; then
enable_atomic_spinlocks=no
else
enable_atomic_spinlocks=yes
fi
fi
if test "x$enable_atomic_spinlocks" = xyes; then
cat >>confdefs.h <<\_ACEOF
#define ATOMIC_SPINLOCK 1
_ACEOF
else
if test "x$have_atomic64_t" = xno; then
{ { echo "$as_me:$LINENO: error: --disable-atomic-spinlocks given but required atomic64 support is unavailable
See \`config.log' for more details." >&5
echo "$as_me: error: --disable-atomic-spinlocks given but required atomic64 support is unavailable
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
echo "$as_me:$LINENO: checking whether atomic types use spinlocks" >&5
echo $ECHO_N "checking whether atomic types use spinlocks... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $enable_atomic_spinlocks" >&5
echo "${ECHO_T}$enable_atomic_spinlocks" >&6
echo "$as_me:$LINENO: checking whether kernel defines atomic64_t" >&5
echo $ECHO_N "checking whether kernel defines atomic64_t... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $have_atomic64_t" >&5
echo "${ECHO_T}$have_atomic64_t" >&6
echo "$as_me:$LINENO: checking whether kernel defines atomic64_cmpxchg" >&5
echo $ECHO_N "checking whether kernel defines atomic64_cmpxchg... $ECHO_C" >&6
@@ -22676,6 +22676,70 @@ echo "${ECHO_T}no" >&6
fi
rm -Rf build
echo "$as_me:$LINENO: checking whether kernel defines uintptr_t" >&5
echo $ECHO_N "checking whether kernel defines uintptr_t... $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 <linux/types.h>
int
main (void)
{
uintptr_t *ptr;
;
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_UINTPTR_T 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