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

View File

@ -25,10 +25,9 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_DEBUG_KMEM SPL_AC_DEBUG_KMEM
SPL_AC_DEBUG_KMEM_TRACKING SPL_AC_DEBUG_KMEM_TRACKING
SPL_AC_ATOMIC_SPINLOCK SPL_AC_ATOMIC_SPINLOCK
SPL_AC_TYPE_UINTPTR_T
SPL_AC_TYPE_ATOMIC64_T
SPL_AC_TYPE_ATOMIC64_CMPXCHG SPL_AC_TYPE_ATOMIC64_CMPXCHG
SPL_AC_TYPE_ATOMIC64_XCHG SPL_AC_TYPE_ATOMIC64_XCHG
SPL_AC_TYPE_UINTPTR_T
SPL_AC_3ARGS_INIT_WORK SPL_AC_3ARGS_INIT_WORK
SPL_AC_2ARGS_REGISTER_SYSCTL SPL_AC_2ARGS_REGISTER_SYSCTL
SPL_AC_SET_SHRINKER SPL_AC_SET_SHRINKER
@ -285,27 +284,6 @@ AC_DEFUN([SPL_AC_DEBUG_KMEM_TRACKING], [
AC_MSG_RESULT([$enable_debug_kmem_tracking]) AC_MSG_RESULT([$enable_debug_kmem_tracking])
]) ])
dnl #
dnl # Use the atomic implemenation based on global spinlocks. This
dnl # should never be needed, however it has been left in place as
dnl # a fallback option in case problems are observed with directly
dnl # mapping to the native Linux atomic operations.
dnl #
AC_DEFUN([SPL_AC_ATOMIC_SPINLOCK], [
AC_ARG_ENABLE([atomic-spinlocks],
[AS_HELP_STRING([--enable-atomic-spinlocks],
[Atomic types use spinlocks @<:@default=no@:>@])],
[],
[enable_atomic_spinlocks=no])
AS_IF([test "x$enable_atomic_spinlocks" = xyes],
[AC_DEFINE([ATOMIC_SPINLOCK], [1],
[Atomic types use spinlocks])])
AC_MSG_CHECKING([whether atomic types use spinlocks])
AC_MSG_RESULT([$enable_atomic_spinlocks])
])
dnl # dnl #
dnl # SPL_LINUX_CONFTEST dnl # SPL_LINUX_CONFTEST
dnl # dnl #
@ -433,41 +411,55 @@ AC_DEFUN([SPL_CHECK_HEADER],
]) ])
dnl # dnl #
dnl # 2.6.24 API change, dnl # Use the atomic implemenation based on global spinlocks. This
dnl # check if uintptr_t typedef is defined dnl # should only be needed by 32-bit kernels which do not provide
dnl # the atomic64_* API. It may be optionally enabled as a fallback
dnl # if problems are observed with the direct mapping to the native
dnl # Linux atomic operations. You may not disable atomic spinlocks
dnl # if you kernel does not an atomic64_* API.
dnl # dnl #
AC_DEFUN([SPL_AC_TYPE_UINTPTR_T], AC_DEFUN([SPL_AC_ATOMIC_SPINLOCK], [
[AC_MSG_CHECKING([whether kernel defines uintptr_t]) AC_ARG_ENABLE([atomic-spinlocks],
SPL_LINUX_TRY_COMPILE([ [AS_HELP_STRING([--enable-atomic-spinlocks],
#include <linux/types.h> [Atomic types use spinlocks @<:@default=check@:>@])],
],[ [],
uintptr_t *ptr; [enable_atomic_spinlocks=check])
],[
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_UINTPTR_T, 1,
[kernel defines uintptr_t])
],[
AC_MSG_RESULT([no])
])
])
dnl #
dnl # 2.6.x API change,
dnl # check if atomic64_t typedef is defined
dnl #
AC_DEFUN([SPL_AC_TYPE_ATOMIC64_T],
[AC_MSG_CHECKING([whether kernel defines atomic64_t])
SPL_LINUX_TRY_COMPILE([ SPL_LINUX_TRY_COMPILE([
#include <asm/atomic.h> #include <asm/atomic.h>
],[ ],[
atomic64_t *ptr; atomic64_t *ptr;
],[ ],[
AC_MSG_RESULT([yes]) have_atomic64_t=yes
AC_DEFINE(HAVE_ATOMIC64_T, 1, AC_DEFINE(HAVE_ATOMIC64_T, 1,
[kernel defines atomic64_t]) [kernel defines atomic64_t])
],[ ],[
AC_MSG_RESULT([no]) have_atomic64_t=no
]) ])
AS_IF([test "x$enable_atomic_spinlocks" = xcheck], [
AS_IF([test "x$have_atomic64_t" = xyes], [
enable_atomic_spinlocks=no
],[
enable_atomic_spinlocks=yes
])
])
AS_IF([test "x$enable_atomic_spinlocks" = xyes], [
AC_DEFINE([ATOMIC_SPINLOCK], [1],
[Atomic types use spinlocks])
],[
AS_IF([test "x$have_atomic64_t" = xno], [
AC_MSG_FAILURE(
[--disable-atomic-spinlocks given but required atomic64 support is unavailable])
])
])
AC_MSG_CHECKING([whether atomic types use spinlocks])
AC_MSG_RESULT([$enable_atomic_spinlocks])
AC_MSG_CHECKING([whether kernel defines atomic64_t])
AC_MSG_RESULT([$have_atomic64_t])
]) ])
dnl # dnl #
@ -508,6 +500,25 @@ AC_DEFUN([SPL_AC_TYPE_ATOMIC64_XCHG],
]) ])
]) ])
dnl #
dnl # 2.6.24 API change,
dnl # check if uintptr_t typedef is defined
dnl #
AC_DEFUN([SPL_AC_TYPE_UINTPTR_T],
[AC_MSG_CHECKING([whether kernel defines uintptr_t])
SPL_LINUX_TRY_COMPILE([
#include <linux/types.h>
],[
uintptr_t *ptr;
],[
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_UINTPTR_T, 1,
[kernel defines uintptr_t])
],[
AC_MSG_RESULT([no])
])
])
dnl # dnl #
dnl # 2.6.20 API change, dnl # 2.6.20 API change,
dnl # INIT_WORK use 2 args and not store data inside dnl # INIT_WORK use 2 args and not store data inside

406
configure vendored
View File

@ -1039,7 +1039,7 @@ Optional Features:
--enable-debug-kmem-tracking --enable-debug-kmem-tracking
Enable detailed kmem tracking [default=no] Enable detailed kmem tracking [default=no]
--enable-atomic-spinlocks --enable-atomic-spinlocks
Atomic types use spinlocks [default=no] Atomic types use spinlocks [default=check]
Optional Packages: Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -19160,89 +19160,9 @@ if test "${enable_atomic_spinlocks+set}" = set; then
enableval="$enable_atomic_spinlocks" enableval="$enable_atomic_spinlocks"
else else
enable_atomic_spinlocks=no enable_atomic_spinlocks=check
fi; 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 cat >conftest.c <<_ACEOF
@ -19282,8 +19202,7 @@ _ACEOF
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then (exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5 have_atomic64_t=yes
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF cat >>confdefs.h <<\_ACEOF
#define HAVE_ATOMIC64_T 1 #define HAVE_ATOMIC64_T 1
@ -19294,8 +19213,7 @@ else
echo "$as_me: failed program was:" >&5 echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5 sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5 have_atomic64_t=no
echo "${ECHO_T}no" >&6
@ -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 "$as_me:$LINENO: checking whether kernel defines atomic64_cmpxchg" >&5
echo $ECHO_N "checking whether kernel defines atomic64_cmpxchg... $ECHO_C" >&6 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 fi
rm -Rf build rm -Rf build
@ -22409,89 +22441,9 @@ if test "${enable_atomic_spinlocks+set}" = set; then
enableval="$enable_atomic_spinlocks" enableval="$enable_atomic_spinlocks"
else else
enable_atomic_spinlocks=no enable_atomic_spinlocks=check
fi; 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 cat >conftest.c <<_ACEOF
@ -22531,8 +22483,7 @@ _ACEOF
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then (exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5 have_atomic64_t=yes
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF cat >>confdefs.h <<\_ACEOF
#define HAVE_ATOMIC64_T 1 #define HAVE_ATOMIC64_T 1
@ -22543,8 +22494,7 @@ else
echo "$as_me: failed program was:" >&5 echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5 sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5 have_atomic64_t=no
echo "${ECHO_T}no" >&6
@ -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 "$as_me:$LINENO: checking whether kernel defines atomic64_cmpxchg" >&5
echo $ECHO_N "checking whether kernel defines atomic64_cmpxchg... $ECHO_C" >&6 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 fi
rm -Rf build rm -Rf build

View File

@ -3,7 +3,6 @@
# location. We do not want to be using $includedir for this. # location. We do not want to be using $includedir for this.
# Installation is handled by the custom install-data-local rule. # Installation is handled by the custom install-data-local rule.
noinst_HEADERS = *.h noinst_HEADERS = *.h
noinst_HEADERS += asm/*.h
noinst_HEADERS += fs/*.h noinst_HEADERS += fs/*.h
noinst_HEADERS += linux/*.h noinst_HEADERS += linux/*.h
noinst_HEADERS += rpc/*.h noinst_HEADERS += rpc/*.h

View File

@ -184,8 +184,8 @@ target_vendor = @target_vendor@
# noinst_HEADERS because they are not installed in the usual include # noinst_HEADERS because they are not installed in the usual include
# location. We do not want to be using $includedir for this. # location. We do not want to be using $includedir for this.
# Installation is handled by the custom install-data-local rule. # Installation is handled by the custom install-data-local rule.
noinst_HEADERS = *.h asm/*.h fs/*.h linux/*.h rpc/*.h sharefs/*.h \ noinst_HEADERS = *.h fs/*.h linux/*.h rpc/*.h sharefs/*.h sys/fm/*.h \
sys/fm/*.h sys/fs/*.h sys/sysevent/*.h sys/*.h util/*.h vm/*.h sys/fs/*.h sys/sysevent/*.h sys/*.h util/*.h vm/*.h
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
@ -278,7 +278,7 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES) distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/asm $(distdir)/fs $(distdir)/linux $(distdir)/rpc $(distdir)/sharefs $(distdir)/sys $(distdir)/sys/fm $(distdir)/sys/fs $(distdir)/sys/sysevent $(distdir)/util $(distdir)/vm $(mkdir_p) $(distdir)/fs $(distdir)/linux $(distdir)/rpc $(distdir)/sharefs $(distdir)/sys $(distdir)/sys/fm $(distdir)/sys/fs $(distdir)/sys/sysevent $(distdir)/util $(distdir)/vm
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \ list='$(DISTFILES)'; for file in $$list; do \

View File

@ -1,414 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = include/asm
DIST_COMMON = $(nobase_include_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/spl-build.m4 \
$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/spl_config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(includedir)"
nobase_includeHEADERS_INSTALL = $(install_sh_DATA)
HEADERS = $(nobase_include_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KERNELCFLAGS = @KERNELCFLAGS@
KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LINUX = @LINUX@
LINUX_OBJ = @LINUX_OBJ@
LINUX_VERSION = @LINUX_VERSION@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPL_META_ALIAS = @SPL_META_ALIAS@
SPL_META_AUTHOR = @SPL_META_AUTHOR@
SPL_META_DATA = @SPL_META_DATA@
SPL_META_LT_AGE = @SPL_META_LT_AGE@
SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
SPL_META_NAME = @SPL_META_NAME@
SPL_META_RELEASE = @SPL_META_RELEASE@
SPL_META_VERSION = @SPL_META_VERSION@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
nobase_include_HEADERS = *.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/asm/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu include/asm/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
install-nobase_includeHEADERS: $(nobase_include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
@$(am__vpath_adj_setup) \
list='$(nobase_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
$(am__vpath_adj) \
echo " $(nobase_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
$(nobase_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
done
uninstall-nobase_includeHEADERS:
@$(NORMAL_UNINSTALL)
@$(am__vpath_adj_setup) \
list='$(nobase_include_HEADERS)'; for p in $$list; do \
$(am__vpath_adj) \
echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
rm -f "$(DESTDIR)$(includedir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-nobase_includeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-nobase_includeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags distclean distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-nobase_includeHEADERS \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-nobase_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,99 +0,0 @@
#ifndef _SPL_ATOMIC_COMPAT_H
#define _SPL_ATOMIC_COMPAT_H
#include <asm/atomic.h>
#include <spl_config.h>
#ifndef HAVE_ATOMIC64_T
#include <linux/spinlock.h>
typedef struct {
spinlock_t lock;
__s64 val;
} atomic64_t;
#define ATOMIC64_INIT(i) { .lock = SPIN_LOCK_UNLOCKED, .val = (i) }
static inline void atomic64_add(__s64 i, atomic64_t *v)
{
unsigned long flags;
spin_lock_irqsave(&v->lock, flags);
v->val += i;
spin_unlock_irqrestore(&v->lock, flags);
}
static inline void atomic64_sub(__s64 i, atomic64_t *v)
{
unsigned long flags;
spin_lock_irqsave(&v->lock, flags);
v->val -= i;
spin_unlock_irqrestore(&v->lock, flags);
}
#define atomic64_inc(v) (atomic64_add(1, (v)))
#define atomic64_dec(v) (atomic64_sub(1, (v)))
static inline __s64 atomic64_add_return(__s64 i, atomic64_t *v)
{
unsigned long flags;
__s64 ret;
spin_lock_irqsave(&v->lock, flags);
v->val += i;
ret = v->val;
spin_unlock_irqrestore(&v->lock, flags);
return ret;
}
static inline __s64 atomic64_sub_return(__s64 i, atomic64_t *v)
{
unsigned long flags;
__s64 ret;
spin_lock_irqsave(&v->lock, flags);
v->val -= i;
ret = v->val;
spin_unlock_irqrestore(&v->lock, flags);
return ret;
}
#define atomic64_inc_return(v) (atomic64_add_return(1, (v)))
#define atomic64_dec_return(v) (atomic64_sub_return(1, (v)))
static inline __s64 atomic64_read(atomic64_t *v)
{
unsigned long flags;
__s64 r;
spin_lock_irqsave(&v->lock, flags);
r = v->val;
spin_unlock_irqrestore(&v->lock, flags);
return r;
}
static inline void atomic64_set(atomic64_t *v, __s64 i)
{
unsigned long flags;
spin_lock_irqsave(&v->lock, flags);
v->val = i;
spin_unlock_irqrestore(&v->lock, flags);
}
#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 */

View File

@ -30,7 +30,14 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <sys/types.h> #include <sys/types.h>
#include <asm/atomic_compat.h>
#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
/* /*
* Two approaches to atomic operations are implemented each with its * Two approaches to atomic operations are implemented each with its

View File

@ -41,7 +41,7 @@ extern "C" {
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <asm/atomic_compat.h> #include <asm/atomic.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <sys/vmsystm.h> #include <sys/vmsystm.h>
@ -109,12 +109,40 @@ kmalloc_node_nofail(size_t size, gfp_t flags, int node)
#endif /* HAVE_KMALLOC_NODE */ #endif /* HAVE_KMALLOC_NODE */
#ifdef DEBUG_KMEM #ifdef DEBUG_KMEM
# ifdef HAVE_ATOMIC64_T
extern atomic64_t kmem_alloc_used; extern atomic64_t kmem_alloc_used;
extern unsigned long long kmem_alloc_max; extern unsigned long long kmem_alloc_max;
extern atomic64_t vmem_alloc_used; extern atomic64_t vmem_alloc_used;
extern unsigned long long vmem_alloc_max; extern unsigned long long vmem_alloc_max;
# define kmem_alloc_used_add(size) atomic64_add(size, &kmem_alloc_used)
# define kmem_alloc_used_sub(size) atomic64_sub(size, &kmem_alloc_used)
# define kmem_alloc_used_read() atomic64_read(&kmem_alloc_used)
# define kmem_alloc_used_set(size) atomic64_set(&kmem_alloc_used, size)
# define vmem_alloc_used_add(size) atomic64_add(size, &vmem_alloc_used)
# define vmem_alloc_used_sub(size) atomic64_sub(size, &vmem_alloc_used)
# define vmem_alloc_used_read() atomic64_read(&vmem_alloc_used)
# define vmem_alloc_used_set(size) atomic64_set(&vmem_alloc_used, size)
# else
extern atomic_t kmem_alloc_used;
extern unsigned long long kmem_alloc_max;
extern atomic_t vmem_alloc_used;
extern unsigned long long vmem_alloc_max;
# define kmem_alloc_used_add(size) atomic_add(size, &kmem_alloc_used)
# define kmem_alloc_used_sub(size) atomic_sub(size, &kmem_alloc_used)
# define kmem_alloc_used_read() atomic_read(&kmem_alloc_used)
# define kmem_alloc_used_set(size) atomic_set(&kmem_alloc_used, size)
# define vmem_alloc_used_add(size) atomic_add(size, &vmem_alloc_used)
# define vmem_alloc_used_sub(size) atomic_sub(size, &vmem_alloc_used)
# define vmem_alloc_used_read() atomic_read(&vmem_alloc_used)
# define vmem_alloc_used_set(size) atomic_set(&vmem_alloc_used, size)
# endif /* _LP64 */
# define kmem_alloc(size, flags) __kmem_alloc((size), (flags), 0, 0) # define kmem_alloc(size, flags) __kmem_alloc((size), (flags), 0, 0)
# define kmem_zalloc(size, flags) __kmem_alloc((size), ((flags) | \ # define kmem_zalloc(size, flags) __kmem_alloc((size), ((flags) | \
__GFP_ZERO), 0, 0) __GFP_ZERO), 0, 0)

View File

@ -215,11 +215,19 @@ EXPORT_SYMBOL(vmem_size);
* report any memory leaked when the module is unloaded. * report any memory leaked when the module is unloaded.
*/ */
#ifdef DEBUG_KMEM #ifdef DEBUG_KMEM
/* Shim layer memory accounting */ /* Shim layer memory accounting */
# ifdef HAVE_ATOMIC64_T
atomic64_t kmem_alloc_used = ATOMIC64_INIT(0); atomic64_t kmem_alloc_used = ATOMIC64_INIT(0);
unsigned long long kmem_alloc_max = 0; unsigned long long kmem_alloc_max = 0;
atomic64_t vmem_alloc_used = ATOMIC64_INIT(0); atomic64_t vmem_alloc_used = ATOMIC64_INIT(0);
unsigned long long vmem_alloc_max = 0; unsigned long long vmem_alloc_max = 0;
# else
atomic_t kmem_alloc_used = ATOMIC_INIT(0);
unsigned long long kmem_alloc_max = 0;
atomic_t vmem_alloc_used = ATOMIC_INIT(0);
unsigned long long vmem_alloc_max = 0;
# endif /* _LP64 */
int kmem_warning_flag = 1; int kmem_warning_flag = 1;
EXPORT_SYMBOL(kmem_alloc_used); EXPORT_SYMBOL(kmem_alloc_used);
@ -392,7 +400,7 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
if (unlikely((size) > (PAGE_SIZE * 2)) && kmem_warning_flag) if (unlikely((size) > (PAGE_SIZE * 2)) && kmem_warning_flag)
CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n", CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n",
(unsigned long long) size, flags, (unsigned long long) size, flags,
atomic64_read(&kmem_alloc_used), kmem_alloc_max); kmem_alloc_used_read(), kmem_alloc_max);
/* We use kstrdup() below because the string pointed to by /* We use kstrdup() below because the string pointed to by
* __FUNCTION__ might not be available by the time we want * __FUNCTION__ might not be available by the time we want
@ -402,7 +410,7 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
kfree(dptr); kfree(dptr);
CWARN("kstrdup() failed in kmem_alloc(%llu, 0x%x) " CWARN("kstrdup() failed in kmem_alloc(%llu, 0x%x) "
"(%lld/%llu)\n", (unsigned long long) size, flags, "(%lld/%llu)\n", (unsigned long long) size, flags,
atomic64_read(&kmem_alloc_used), kmem_alloc_max); kmem_alloc_used_read(), kmem_alloc_max);
goto out; goto out;
} }
@ -421,15 +429,13 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
kfree(dptr); kfree(dptr);
CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n", CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
(unsigned long long) size, flags, (unsigned long long) size, flags,
atomic64_read(&kmem_alloc_used), kmem_alloc_max); kmem_alloc_used_read(), kmem_alloc_max);
goto out; goto out;
} }
atomic64_add(size, &kmem_alloc_used); kmem_alloc_used_add(size);
if (unlikely(atomic64_read(&kmem_alloc_used) > if (unlikely(kmem_alloc_used_read() > kmem_alloc_max))
kmem_alloc_max)) kmem_alloc_max = kmem_alloc_used_read();
kmem_alloc_max =
atomic64_read(&kmem_alloc_used);
INIT_HLIST_NODE(&dptr->kd_hlist); INIT_HLIST_NODE(&dptr->kd_hlist);
INIT_LIST_HEAD(&dptr->kd_list); INIT_LIST_HEAD(&dptr->kd_list);
@ -446,7 +452,7 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
CDEBUG_LIMIT(D_INFO, "kmem_alloc(%llu, 0x%x) = %p " CDEBUG_LIMIT(D_INFO, "kmem_alloc(%llu, 0x%x) = %p "
"(%lld/%llu)\n", (unsigned long long) size, flags, "(%lld/%llu)\n", (unsigned long long) size, flags,
ptr, atomic64_read(&kmem_alloc_used), ptr, kmem_alloc_used_read(),
kmem_alloc_max); kmem_alloc_max);
} }
out: out:
@ -472,10 +478,9 @@ kmem_free_track(void *ptr, size_t size)
"kd_func = %s, kd_line = %d\n", (unsigned long long) dptr->kd_size, "kd_func = %s, kd_line = %d\n", (unsigned long long) dptr->kd_size,
(unsigned long long) size, dptr->kd_func, dptr->kd_line); (unsigned long long) size, dptr->kd_func, dptr->kd_line);
atomic64_sub(size, &kmem_alloc_used); kmem_alloc_used_sub(size);
CDEBUG_LIMIT(D_INFO, "kmem_free(%p, %llu) (%lld/%llu)\n", ptr, CDEBUG_LIMIT(D_INFO, "kmem_free(%p, %llu) (%lld/%llu)\n", ptr,
(unsigned long long) size, atomic64_read(&kmem_alloc_used), (unsigned long long) size, kmem_alloc_used_read(),
kmem_alloc_max); kmem_alloc_max);
kfree(dptr->kd_func); kfree(dptr->kd_func);
@ -513,7 +518,7 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
kfree(dptr); kfree(dptr);
CWARN("kstrdup() failed in vmem_alloc(%llu, 0x%x) " CWARN("kstrdup() failed in vmem_alloc(%llu, 0x%x) "
"(%lld/%llu)\n", (unsigned long long) size, flags, "(%lld/%llu)\n", (unsigned long long) size, flags,
atomic64_read(&vmem_alloc_used), vmem_alloc_max); vmem_alloc_used_read(), vmem_alloc_max);
goto out; goto out;
} }
@ -525,18 +530,16 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
kfree(dptr); kfree(dptr);
CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n", CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
(unsigned long long) size, flags, (unsigned long long) size, flags,
atomic64_read(&vmem_alloc_used), vmem_alloc_max); vmem_alloc_used_read(), vmem_alloc_max);
goto out; goto out;
} }
if (flags & __GFP_ZERO) if (flags & __GFP_ZERO)
memset(ptr, 0, size); memset(ptr, 0, size);
atomic64_add(size, &vmem_alloc_used); vmem_alloc_used_add(size);
if (unlikely(atomic64_read(&vmem_alloc_used) > if (unlikely(vmem_alloc_used_read() > vmem_alloc_max))
vmem_alloc_max)) vmem_alloc_max = vmem_alloc_used_read();
vmem_alloc_max =
atomic64_read(&vmem_alloc_used);
INIT_HLIST_NODE(&dptr->kd_hlist); INIT_HLIST_NODE(&dptr->kd_hlist);
INIT_LIST_HEAD(&dptr->kd_list); INIT_LIST_HEAD(&dptr->kd_list);
@ -553,7 +556,7 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
CDEBUG_LIMIT(D_INFO, "vmem_alloc(%llu, 0x%x) = %p " CDEBUG_LIMIT(D_INFO, "vmem_alloc(%llu, 0x%x) = %p "
"(%lld/%llu)\n", (unsigned long long) size, flags, "(%lld/%llu)\n", (unsigned long long) size, flags,
ptr, atomic64_read(&vmem_alloc_used), ptr, vmem_alloc_used_read(),
vmem_alloc_max); vmem_alloc_max);
} }
out: out:
@ -578,9 +581,9 @@ vmem_free_track(void *ptr, size_t size)
"kd_func = %s, kd_line = %d\n", (unsigned long long) dptr->kd_size, "kd_func = %s, kd_line = %d\n", (unsigned long long) dptr->kd_size,
(unsigned long long) size, dptr->kd_func, dptr->kd_line); (unsigned long long) size, dptr->kd_func, dptr->kd_line);
atomic64_sub(size, &vmem_alloc_used); vmem_alloc_used_sub(size);
CDEBUG_LIMIT(D_INFO, "vmem_free(%p, %llu) (%lld/%llu)\n", ptr, CDEBUG_LIMIT(D_INFO, "vmem_free(%p, %llu) (%lld/%llu)\n", ptr,
(unsigned long long) size, atomic64_read(&vmem_alloc_used), (unsigned long long) size, vmem_alloc_used_read(),
vmem_alloc_max); vmem_alloc_max);
kfree(dptr->kd_func); kfree(dptr->kd_func);
@ -609,7 +612,7 @@ kmem_alloc_debug(size_t size, int flags, const char *func, int line,
if (unlikely(size > (PAGE_SIZE * 2)) && kmem_warning_flag) if (unlikely(size > (PAGE_SIZE * 2)) && kmem_warning_flag)
CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n", CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n",
(unsigned long long) size, flags, (unsigned long long) size, flags,
atomic64_read(&kmem_alloc_used), kmem_alloc_max); kmem_alloc_used_read(), kmem_alloc_max);
/* Use the correct allocator */ /* Use the correct allocator */
if (node_alloc) { if (node_alloc) {
@ -624,15 +627,15 @@ kmem_alloc_debug(size_t size, int flags, const char *func, int line,
if (ptr == NULL) { if (ptr == NULL) {
CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n", CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
(unsigned long long) size, flags, (unsigned long long) size, flags,
atomic64_read(&kmem_alloc_used), kmem_alloc_max); kmem_alloc_used_read(), kmem_alloc_max);
} else { } else {
atomic64_add(size, &kmem_alloc_used); kmem_alloc_used_add(size);
if (unlikely(atomic64_read(&kmem_alloc_used) > kmem_alloc_max)) if (unlikely(kmem_alloc_used_read() > kmem_alloc_max))
kmem_alloc_max = atomic64_read(&kmem_alloc_used); kmem_alloc_max = kmem_alloc_used_read();
CDEBUG_LIMIT(D_INFO, "kmem_alloc(%llu, 0x%x) = %p " CDEBUG_LIMIT(D_INFO, "kmem_alloc(%llu, 0x%x) = %p "
"(%lld/%llu)\n", (unsigned long long) size, flags, ptr, "(%lld/%llu)\n", (unsigned long long) size, flags, ptr,
atomic64_read(&kmem_alloc_used), kmem_alloc_max); kmem_alloc_used_read(), kmem_alloc_max);
} }
RETURN(ptr); RETURN(ptr);
} }
@ -646,10 +649,9 @@ kmem_free_debug(void *ptr, size_t size)
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr, ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
(unsigned long long) size); (unsigned long long) size);
atomic64_sub(size, &kmem_alloc_used); kmem_alloc_used_sub(size);
CDEBUG_LIMIT(D_INFO, "kmem_free(%p, %llu) (%lld/%llu)\n", ptr, CDEBUG_LIMIT(D_INFO, "kmem_free(%p, %llu) (%lld/%llu)\n", ptr,
(unsigned long long) size, atomic64_read(&kmem_alloc_used), (unsigned long long) size, kmem_alloc_used_read(),
kmem_alloc_max); kmem_alloc_max);
memset(ptr, 0x5a, size); memset(ptr, 0x5a, size);
@ -672,19 +674,18 @@ vmem_alloc_debug(size_t size, int flags, const char *func, int line)
if (ptr == NULL) { if (ptr == NULL) {
CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n", CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
(unsigned long long) size, flags, (unsigned long long) size, flags,
atomic64_read(&vmem_alloc_used), vmem_alloc_max); vmem_alloc_used_read(), vmem_alloc_max);
} else { } else {
if (flags & __GFP_ZERO) if (flags & __GFP_ZERO)
memset(ptr, 0, size); memset(ptr, 0, size);
atomic64_add(size, &vmem_alloc_used); vmem_alloc_used_add(size);
if (unlikely(vmem_alloc_used_read() > vmem_alloc_max))
if (unlikely(atomic64_read(&vmem_alloc_used) > vmem_alloc_max)) vmem_alloc_max = vmem_alloc_used_read();
vmem_alloc_max = atomic64_read(&vmem_alloc_used);
CDEBUG_LIMIT(D_INFO, "vmem_alloc(%llu, 0x%x) = %p " CDEBUG_LIMIT(D_INFO, "vmem_alloc(%llu, 0x%x) = %p "
"(%lld/%llu)\n", (unsigned long long) size, flags, ptr, "(%lld/%llu)\n", (unsigned long long) size, flags, ptr,
atomic64_read(&vmem_alloc_used), vmem_alloc_max); vmem_alloc_used_read(), vmem_alloc_max);
} }
RETURN(ptr); RETURN(ptr);
@ -699,10 +700,9 @@ vmem_free_debug(void *ptr, size_t size)
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr, ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
(unsigned long long) size); (unsigned long long) size);
atomic64_sub(size, &vmem_alloc_used); vmem_alloc_used_sub(size);
CDEBUG_LIMIT(D_INFO, "vmem_free(%p, %llu) (%lld/%llu)\n", ptr, CDEBUG_LIMIT(D_INFO, "vmem_free(%p, %llu) (%lld/%llu)\n", ptr,
(unsigned long long) size, atomic64_read(&vmem_alloc_used), (unsigned long long) size, vmem_alloc_used_read(),
vmem_alloc_max); vmem_alloc_max);
memset(ptr, 0x5a, size); memset(ptr, 0x5a, size);
@ -1969,8 +1969,8 @@ spl_kmem_init(void)
#endif #endif
#ifdef DEBUG_KMEM #ifdef DEBUG_KMEM
atomic64_set(&kmem_alloc_used, 0); kmem_alloc_used_set(0);
atomic64_set(&vmem_alloc_used, 0); vmem_alloc_used_set(0);
spl_kmem_init_tracking(&kmem_list, &kmem_lock, KMEM_TABLE_SIZE); spl_kmem_init_tracking(&kmem_list, &kmem_lock, KMEM_TABLE_SIZE);
spl_kmem_init_tracking(&vmem_list, &vmem_lock, VMEM_TABLE_SIZE); spl_kmem_init_tracking(&vmem_list, &vmem_lock, VMEM_TABLE_SIZE);
@ -1986,14 +1986,14 @@ spl_kmem_fini(void)
* allocation size and the first few bytes of what's located * allocation size and the first few bytes of what's located
* at that address to aid in debugging. Performance is not * at that address to aid in debugging. Performance is not
* a serious concern here since it is module unload time. */ * a serious concern here since it is module unload time. */
if (atomic64_read(&kmem_alloc_used) != 0) if (kmem_alloc_used_read() != 0)
CWARN("kmem leaked %ld/%ld bytes\n", CWARN("kmem leaked %ld/%ld bytes\n",
atomic64_read(&kmem_alloc_used), kmem_alloc_max); kmem_alloc_used_read(), kmem_alloc_max);
if (atomic64_read(&vmem_alloc_used) != 0) if (vmem_alloc_used_read() != 0)
CWARN("vmem leaked %ld/%ld bytes\n", CWARN("vmem leaked %ld/%ld bytes\n",
atomic64_read(&vmem_alloc_used), vmem_alloc_max); vmem_alloc_used_read(), vmem_alloc_max);
spl_kmem_fini_tracking(&kmem_list, &kmem_lock); spl_kmem_fini_tracking(&kmem_list, &kmem_lock);
spl_kmem_fini_tracking(&vmem_list, &vmem_lock); spl_kmem_fini_tracking(&vmem_list, &vmem_lock);

View File

@ -409,8 +409,8 @@ proc_console_backoff(struct ctl_table *table, int write, struct file *filp,
#ifdef DEBUG_KMEM #ifdef DEBUG_KMEM
static int static int
proc_doatomic64(struct ctl_table *table, int write, struct file *filp, proc_domemused(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos) void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
int rc = 0; int rc = 0;
unsigned long min = 0, max = ~0, val; unsigned long min = 0, max = ~0, val;
@ -425,7 +425,11 @@ proc_doatomic64(struct ctl_table *table, int write, struct file *filp,
if (write) { if (write) {
*ppos += *lenp; *ppos += *lenp;
} else { } else {
# ifdef HAVE_ATOMIC64_T
val = atomic64_read((atomic64_t *)table->data); val = atomic64_read((atomic64_t *)table->data);
# else
val = atomic_read((atomic_t *)table->data);
# endif /* HAVE_ATOMIC64_T */
rc = proc_doulongvec_minmax(&dummy, write, filp, rc = proc_doulongvec_minmax(&dummy, write, filp,
buffer, lenp, ppos); buffer, lenp, ppos);
} }
@ -861,9 +865,13 @@ static struct ctl_table spl_kmem_table[] = {
.ctl_name = CTL_KMEM_KMEMUSED, .ctl_name = CTL_KMEM_KMEMUSED,
.procname = "kmem_used", .procname = "kmem_used",
.data = &kmem_alloc_used, .data = &kmem_alloc_used,
# ifdef HAVE_ATOMIC64_T
.maxlen = sizeof(atomic64_t), .maxlen = sizeof(atomic64_t),
# else
.maxlen = sizeof(atomic_t),
# endif /* HAVE_ATOMIC64_T */
.mode = 0444, .mode = 0444,
.proc_handler = &proc_doatomic64, .proc_handler = &proc_domemused,
}, },
{ {
.ctl_name = CTL_KMEM_KMEMMAX, .ctl_name = CTL_KMEM_KMEMMAX,
@ -879,9 +887,13 @@ static struct ctl_table spl_kmem_table[] = {
.ctl_name = CTL_KMEM_VMEMUSED, .ctl_name = CTL_KMEM_VMEMUSED,
.procname = "vmem_used", .procname = "vmem_used",
.data = &vmem_alloc_used, .data = &vmem_alloc_used,
# ifdef HAVE_ATOMIC64_T
.maxlen = sizeof(atomic64_t), .maxlen = sizeof(atomic64_t),
# else
.maxlen = sizeof(atomic_t),
# endif /* HAVE_ATOMIC64_T */
.mode = 0444, .mode = 0444,
.proc_handler = &proc_doatomic64, .proc_handler = &proc_domemused,
}, },
{ {
.ctl_name = CTL_KMEM_VMEMMAX, .ctl_name = CTL_KMEM_VMEMMAX,