SPL_AC_DEBUG
SPL_AC_DEBUG_KMEM
- SPL_AC_DEBUG_KSTAT
- SPL_AC_DEBUG_CALLB
+ SPL_AC_DEBUG_KMEM_TRACKING
SPL_AC_ATOMIC_SPINLOCK
SPL_AC_TYPE_UINTPTR_T
SPL_AC_TYPE_ATOMIC64_T
[test "$SPL_CONFIG" = all])
])
+dnl #
+dnl # Enable if the SPL should be compiled with internal debugging enabled.
+dnl # By default this support is disabled.
+dnl #
AC_DEFUN([SPL_AC_DEBUG], [
+ AC_ARG_ENABLE([debug],
+ [AS_HELP_STRING([--enable-debug],
+ [Enable generic debug support @<:@default=no@:>@])],
+ [],
+ [enable_debug=no])
+
+ AS_IF([test "x$enable_debug" = xyes],
+ [KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG"],
+ [KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"])
+
AC_MSG_CHECKING([whether debugging is enabled])
- AC_ARG_ENABLE( [debug],
- AS_HELP_STRING([--enable-debug],
- [Enable generic debug support (default off)]),
- [ case "$enableval" in
- yes) spl_ac_debug=yes ;;
- no) spl_ac_debug=no ;;
- *) AC_MSG_RESULT([Error!])
- AC_MSG_ERROR([Bad value "$enableval" for --enable-debug]) ;;
- esac ]
- )
- if test "$spl_ac_debug" = yes; then
- AC_MSG_RESULT([yes])
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG"
- else
- AC_MSG_RESULT([no])
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
- fi
+ AC_MSG_RESULT([$enable_debug])
])
+dnl #
+dnl # Enabled by default it provides a minimal level of memory tracking.
+dnl # A total count of bytes allocated is kept for each alloc and free.
+dnl # Then at module unload time a report to the console will be printed
+dnl # if memory was leaked. Additionally, /proc/spl/kmem/slab will exist
+dnl # and provide an easy way to inspect the kmem based slab.
+dnl #
AC_DEFUN([SPL_AC_DEBUG_KMEM], [
- AC_MSG_CHECKING([whether kmem debugging is enabled])
- AC_ARG_ENABLE( [debug-kmem],
- AS_HELP_STRING([--enable-debug-kmem],
- [Enable kmem debug support (default off)]),
- [ case "$enableval" in
- yes) spl_ac_debug_kmem=yes ;;
- no) spl_ac_debug_kmem=no ;;
- *) AC_MSG_RESULT([Error!])
- AC_MSG_ERROR([Bad value "$enableval" for --enable-debug-kmem]) ;;
- esac ]
- )
- if test "$spl_ac_debug_kmem" = yes; then
- AC_MSG_RESULT([yes])
- AC_DEFINE([DEBUG_KMEM], [1],
- [Define to 1 to enable kmem debugging])
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"
- else
- AC_MSG_RESULT([no])
- fi
-])
+ AC_ARG_ENABLE([debug-kmem],
+ [AS_HELP_STRING([--enable-debug-kmem],
+ [Enable basic kmem accounting @<:@default=yes@:>@])],
+ [],
+ [enable_debug_kmem=yes])
-AC_DEFUN([SPL_AC_DEBUG_KSTAT], [
- AC_MSG_CHECKING([whether kstat debugging is enabled])
- AC_ARG_ENABLE( [debug-kstat],
- AS_HELP_STRING([--enable-debug-kstat],
- [Enable kstat debug support (default off)]),
- [ case "$enableval" in
- yes) spl_ac_debug_kstat=yes ;;
- no) spl_ac_debug_kstat=no ;;
- *) AC_MSG_RESULT([Error!])
- AC_MSG_ERROR([Bad value "$enableval" for --enable-debug-kstat]) ;;
- esac ]
- )
- if test "$spl_ac_debug_kstat" = yes; then
- AC_MSG_RESULT([yes])
- AC_DEFINE([DEBUG_KSTAT], [1],
- [Define to 1 to enable kstat debugging])
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KSTAT"
- else
- AC_MSG_RESULT([no])
- fi
+ AS_IF([test "x$enable_debug_kmem" = xyes],
+ [AC_DEFINE([DEBUG_KMEM], [1],
+ [Define to 1 to enable basic kmem accounting])
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"])
+
+ AC_MSG_CHECKING([whether basic kmem accounting is enabled])
+ AC_MSG_RESULT([$enable_debug_kmem])
])
-AC_DEFUN([SPL_AC_DEBUG_CALLB], [
- AC_MSG_CHECKING([whether callb debugging is enabled])
- AC_ARG_ENABLE( [debug-callb],
- AS_HELP_STRING([--enable-debug-callb],
- [Enable callb debug support (default off)]),
- [ case "$enableval" in
- yes) spl_ac_debug_callb=yes ;;
- no) spl_ac_debug_callb=no ;;
- *) AC_MSG_RESULT([Error!])
- AC_MSG_ERROR([Bad value "$enableval" for --enable-debug-callb]) ;;
- esac ]
- )
- if test "$spl_ac_debug_callb" = yes; then
- AC_MSG_RESULT([yes])
- AC_DEFINE([DEBUG_CALLB], [1],
- [Define to 1 to enable callb debugging])
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_CALLB"
- else
- AC_MSG_RESULT([no])
- fi
+dnl #
+dnl # Disabled by default it provides detailed memory tracking. This
+dnl # feature also requires --enable-debug-kmem to be set. When enabled
+dnl # not only will total bytes be tracked but also the location of every
+dnl # alloc and free. When the SPL module is unloaded a list of all leaked
+dnl # addresses and where they were allocated will be dumped to the console.
+dnl # Enabling this feature has a significant impact on performance but it
+dnl # makes finding memory leaks pretty straight forward.
+dnl #
+AC_DEFUN([SPL_AC_DEBUG_KMEM_TRACKING], [
+ AC_ARG_ENABLE([debug-kmem-tracking],
+ [AS_HELP_STRING([--enable-debug-kmem-tracking],
+ [Enable detailed kmem tracking @<:@default=no@:>@])],
+ [],
+ [enable_debug_kmem_tracking=no])
+
+ AS_IF([test "x$enable_debug_kmem_tracking" = xyes],
+ [AC_DEFINE([DEBUG_KMEM_TRACKING], [1],
+ [Define to 1 to enable detailed kmem tracking])
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING"])
+
+ AC_MSG_CHECKING([whether detailed kmem tracking is enabled])
+ AC_MSG_RESULT([$enable_debug_kmem_tracking])
])
dnl #
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
- --enable-debug Enable generic debug support (default off)
- --enable-debug-kmem Enable kmem debug support (default off)
- --enable-debug-kstat Enable kstat debug support (default off)
- --enable-debug-callb Enable callb debug support (default off)
+ --enable-debug Enable generic debug support [default=no]
+ --enable-debug-kmem Enable basic kmem accounting [default=yes]
+ --enable-debug-kmem-tracking
+ Enable detailed kmem tracking [default=no]
--enable-atomic-spinlocks
Atomic types use spinlocks [default=no]
- echo "$as_me:$LINENO: checking whether debugging is enabled" >&5
-echo $ECHO_N "checking whether debugging is enabled... $ECHO_C" >&6
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
enableval="$enable_debug"
- case "$enableval" in
- yes) spl_ac_debug=yes ;;
- no) spl_ac_debug=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
+else
+ enable_debug=no
fi;
- if test "$spl_ac_debug" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
- fi
+
+ if test "x$enable_debug" = xyes; then
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG"
+else
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
+fi
+
+
+ echo "$as_me:$LINENO: checking whether debugging is enabled" >&5
+echo $ECHO_N "checking whether debugging is enabled... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $enable_debug" >&5
+echo "${ECHO_T}$enable_debug" >&6
- echo "$as_me:$LINENO: checking whether kmem debugging is enabled" >&5
-echo $ECHO_N "checking whether kmem debugging is enabled... $ECHO_C" >&6
# Check whether --enable-debug-kmem or --disable-debug-kmem was given.
if test "${enable_debug_kmem+set}" = set; then
enableval="$enable_debug_kmem"
- case "$enableval" in
- yes) spl_ac_debug_kmem=yes ;;
- no) spl_ac_debug_kmem=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug-kmem" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug-kmem" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
+else
+ enable_debug_kmem=yes
fi;
- if test "$spl_ac_debug_kmem" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+
+ if test "x$enable_debug_kmem" = xyes; then
cat >>confdefs.h <<\_ACEOF
#define DEBUG_KMEM 1
_ACEOF
KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- fi
-
-
- echo "$as_me:$LINENO: checking whether kstat debugging is enabled" >&5
-echo $ECHO_N "checking whether kstat debugging is enabled... $ECHO_C" >&6
- # Check whether --enable-debug-kstat or --disable-debug-kstat was given.
-if test "${enable_debug_kstat+set}" = set; then
- enableval="$enable_debug_kstat"
- case "$enableval" in
- yes) spl_ac_debug_kstat=yes ;;
- no) spl_ac_debug_kstat=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug-kstat" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug-kstat" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
-
-fi;
- if test "$spl_ac_debug_kstat" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+fi
-cat >>confdefs.h <<\_ACEOF
-#define DEBUG_KSTAT 1
-_ACEOF
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KSTAT"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- fi
+ echo "$as_me:$LINENO: checking whether basic kmem accounting is enabled" >&5
+echo $ECHO_N "checking whether basic kmem accounting is enabled... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $enable_debug_kmem" >&5
+echo "${ECHO_T}$enable_debug_kmem" >&6
- echo "$as_me:$LINENO: checking whether callb debugging is enabled" >&5
-echo $ECHO_N "checking whether callb debugging is enabled... $ECHO_C" >&6
- # Check whether --enable-debug-callb or --disable-debug-callb was given.
-if test "${enable_debug_callb+set}" = set; then
- enableval="$enable_debug_callb"
- case "$enableval" in
- yes) spl_ac_debug_callb=yes ;;
- no) spl_ac_debug_callb=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug-callb" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug-callb" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
+ # Check whether --enable-debug-kmem-tracking or --disable-debug-kmem-tracking was given.
+if test "${enable_debug_kmem_tracking+set}" = set; then
+ enableval="$enable_debug_kmem_tracking"
+else
+ enable_debug_kmem_tracking=no
fi;
- if test "$spl_ac_debug_callb" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+
+ if test "x$enable_debug_kmem_tracking" = xyes; then
cat >>confdefs.h <<\_ACEOF
-#define DEBUG_CALLB 1
+#define DEBUG_KMEM_TRACKING 1
_ACEOF
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_CALLB"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- fi
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING"
+fi
+
+
+ echo "$as_me:$LINENO: checking whether detailed kmem tracking is enabled" >&5
+echo $ECHO_N "checking whether detailed kmem tracking is enabled... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $enable_debug_kmem_tracking" >&5
+echo "${ECHO_T}$enable_debug_kmem_tracking" >&6
# Check whether --enable-atomic-spinlocks or --disable-atomic-spinlocks was given.
- echo "$as_me:$LINENO: checking whether debugging is enabled" >&5
-echo $ECHO_N "checking whether debugging is enabled... $ECHO_C" >&6
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
enableval="$enable_debug"
- case "$enableval" in
- yes) spl_ac_debug=yes ;;
- no) spl_ac_debug=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
+else
+ enable_debug=no
fi;
- if test "$spl_ac_debug" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
- fi
+
+ if test "x$enable_debug" = xyes; then
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG"
+else
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
+fi
+
+
+ echo "$as_me:$LINENO: checking whether debugging is enabled" >&5
+echo $ECHO_N "checking whether debugging is enabled... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $enable_debug" >&5
+echo "${ECHO_T}$enable_debug" >&6
- echo "$as_me:$LINENO: checking whether kmem debugging is enabled" >&5
-echo $ECHO_N "checking whether kmem debugging is enabled... $ECHO_C" >&6
# Check whether --enable-debug-kmem or --disable-debug-kmem was given.
if test "${enable_debug_kmem+set}" = set; then
enableval="$enable_debug_kmem"
- case "$enableval" in
- yes) spl_ac_debug_kmem=yes ;;
- no) spl_ac_debug_kmem=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug-kmem" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug-kmem" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
+else
+ enable_debug_kmem=yes
fi;
- if test "$spl_ac_debug_kmem" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+
+ if test "x$enable_debug_kmem" = xyes; then
cat >>confdefs.h <<\_ACEOF
#define DEBUG_KMEM 1
_ACEOF
KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- fi
-
-
- echo "$as_me:$LINENO: checking whether kstat debugging is enabled" >&5
-echo $ECHO_N "checking whether kstat debugging is enabled... $ECHO_C" >&6
- # Check whether --enable-debug-kstat or --disable-debug-kstat was given.
-if test "${enable_debug_kstat+set}" = set; then
- enableval="$enable_debug_kstat"
- case "$enableval" in
- yes) spl_ac_debug_kstat=yes ;;
- no) spl_ac_debug_kstat=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug-kstat" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug-kstat" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
-
-fi;
- if test "$spl_ac_debug_kstat" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+fi
-cat >>confdefs.h <<\_ACEOF
-#define DEBUG_KSTAT 1
-_ACEOF
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KSTAT"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- fi
+ echo "$as_me:$LINENO: checking whether basic kmem accounting is enabled" >&5
+echo $ECHO_N "checking whether basic kmem accounting is enabled... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $enable_debug_kmem" >&5
+echo "${ECHO_T}$enable_debug_kmem" >&6
- echo "$as_me:$LINENO: checking whether callb debugging is enabled" >&5
-echo $ECHO_N "checking whether callb debugging is enabled... $ECHO_C" >&6
- # Check whether --enable-debug-callb or --disable-debug-callb was given.
-if test "${enable_debug_callb+set}" = set; then
- enableval="$enable_debug_callb"
- case "$enableval" in
- yes) spl_ac_debug_callb=yes ;;
- no) spl_ac_debug_callb=no ;;
- *) echo "$as_me:$LINENO: result: Error!" >&5
-echo "${ECHO_T}Error!" >&6
- { { echo "$as_me:$LINENO: error: Bad value \"$enableval\" for --enable-debug-callb" >&5
-echo "$as_me: error: Bad value \"$enableval\" for --enable-debug-callb" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
+ # Check whether --enable-debug-kmem-tracking or --disable-debug-kmem-tracking was given.
+if test "${enable_debug_kmem_tracking+set}" = set; then
+ enableval="$enable_debug_kmem_tracking"
+else
+ enable_debug_kmem_tracking=no
fi;
- if test "$spl_ac_debug_callb" = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+
+ if test "x$enable_debug_kmem_tracking" = xyes; then
cat >>confdefs.h <<\_ACEOF
-#define DEBUG_CALLB 1
+#define DEBUG_KMEM_TRACKING 1
_ACEOF
- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_CALLB"
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- fi
+ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING"
+fi
+
+
+ echo "$as_me:$LINENO: checking whether detailed kmem tracking is enabled" >&5
+echo $ECHO_N "checking whether detailed kmem tracking is enabled... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $enable_debug_kmem_tracking" >&5
+echo "${ECHO_T}$enable_debug_kmem_tracking" >&6
# Check whether --enable-atomic-spinlocks or --disable-atomic-spinlocks was given.
#include <linux/module.h>
#include <sys/mutex.h>
-#ifdef DEBUG_CALLB
#define CALLB_CPR_ASSERT(cp) ASSERT(MUTEX_HELD((cp)->cc_lockp));
-#else
-#define CALLB_CPR_ASSERT(cp) (void)0
-#endif
typedef struct callb_cpr {
kmutex_t *cc_lockp;
#endif
#undef DEBUG_KMEM_UNIMPLEMENTED
-#undef DEBUG_KMEM_TRACKING /* Per-allocation memory tracking */
#include <linux/module.h>
#include <linux/slab.h>
#ifndef _SPL_KSTAT_H
#define _SPL_KSTAT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <linux/module.h>
#include <sys/types.h>
#include <sys/time.h>
int kstat_init(void);
void kstat_fini(void);
-#ifdef DEBUG_KSTAT
extern kstat_t *__kstat_create(const char *ks_module, int ks_instance,
const char *ks_name, const char *ks_class,
uchar_t ks_type, uint_t ks_ndata,
#define kstat_install(k) __kstat_install(k)
#define kstat_delete(k) __kstat_delete(k)
-#else
-
-#define kstat_create(m,i,n,c,t,s,f) (NULL)
-#define kstat_install(k) ((void)0)
-#define kstat_delete(k) ((void)0)
-
-#endif /* DEBUG_KSTAT */
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* _SPL_KSTAT_H */
#define spl_unregister_sysctl_table(t) unregister_sysctl_table(t)
#endif /* CONFIG_SYSCTL */
-#ifdef DEBUG_KSTAT
extern struct proc_dir_entry *proc_spl_kstat;
struct proc_dir_entry *proc_dir_entry_find(struct proc_dir_entry *root,
const char *str);
int proc_dir_entries(struct proc_dir_entry *root);
-#endif
int proc_init(void);
void proc_fini(void);
/*
* Memory allocation interfaces and debugging for basic kmem_*
- * and vmem_* style memory allocation. When DEBUG_KMEM is enable
- * all allocations will be tracked when they are allocated and
- * freed. When the SPL module is unload a list of all leaked
- * addresses and where they were allocated will be dumped to the
- * console. Enabling this feature has a significant impant on
- * performance but it makes finding memory leaks staight forward.
+ * and vmem_* style memory allocation. When DEBUG_KMEM is enabled
+ * the SPL will keep track of the total memory allocated, and
+ * report any memory leaked when the module is unloaded.
*/
#ifdef DEBUG_KMEM
/* Shim layer memory accounting */
EXPORT_SYMBOL(vmem_alloc_max);
EXPORT_SYMBOL(kmem_warning_flag);
-# ifdef DEBUG_KMEM_TRACKING
-
-/* XXX - Not to surprisingly with debugging enabled the xmem_locks are very
- * highly contended particularly on xfree(). If we want to run with this
- * detailed debugging enabled for anything other than debugging we need to
- * minimize the contention by moving to a lock per xmem_table entry model.
+/* When DEBUG_KMEM_TRACKING is enabled not only will total bytes be tracked
+ * but also the location of every alloc and free. When the SPL module is
+ * unloaded a list of all leaked addresses and where they were allocated
+ * will be dumped to the console. Enabling this feature has a significant
+ * impact on performance but it makes finding memory leaks straight forward.
+ *
+ * Not surprisingly with debugging enabled the xmem_locks are very highly
+ * contended particularly on xfree(). If we want to run with this detailed
+ * debugging enabled for anything other than debugging we need to minimize
+ * the contention by moving to a lock per xmem_table entry model.
*/
+# ifdef DEBUG_KMEM_TRACKING
# define KMEM_HASH_BITS 10
# define KMEM_TABLE_SIZE (1 << KMEM_HASH_BITS)
#include <sys/kstat.h>
-#ifdef DEBUG_KSTAT
-
static spinlock_t kstat_lock;
static struct list_head kstat_list;
static kid_t kstat_id;
}
EXPORT_SYMBOL(__kstat_delete);
-#endif /* DEBUG_KSTAT */
-
int
kstat_init(void)
{
ENTRY;
-#ifdef DEBUG_KSTAT
spin_lock_init(&kstat_lock);
INIT_LIST_HEAD(&kstat_list);
kstat_id = 0;
-#endif /* DEBUG_KSTAT */
RETURN(0);
}
kstat_fini(void)
{
ENTRY;
-#ifdef DEBUG_KSTAT
ASSERT(list_empty(&kstat_list));
-#endif /* DEBUG_KSTAT */
EXIT;
}
static struct ctl_table_header *spl_header = NULL;
#endif /* CONFIG_SYSCTL */
-#if defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
static struct proc_dir_entry *proc_spl = NULL;
#ifdef DEBUG_KMEM
static struct proc_dir_entry *proc_spl_kmem = NULL;
static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
#endif /* DEBUG_KMEM */
-#ifdef DEBUG_KSTAT
struct proc_dir_entry *proc_spl_kstat = NULL;
-#endif /* DEBUG_KSTAT */
-#endif /* DEBUG_KMEM || DEBUG_KSTAT */
#ifdef HAVE_CTL_UNNUMBERED
};
#endif /* DEBUG_KMEM */
-#ifdef DEBUG_KSTAT
static struct ctl_table spl_kstat_table[] = {
{0},
};
-#endif /* DEBUG_KSTAT */
static struct ctl_table spl_table[] = {
/* NB No .strategy entries have been provided since
.child = spl_kmem_table,
},
#endif
-#ifdef DEBUG_KSTAT
{
.ctl_name = CTL_SPL_KSTAT,
.procname = "kstat",
.mode = 0555,
.child = spl_kstat_table,
},
-#endif
{ 0 },
};
RETURN(-EUNATCH);
#endif /* CONFIG_SYSCTL */
-#if defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
proc_spl = proc_mkdir("spl", NULL);
if (proc_spl == NULL)
GOTO(out, rc = -EUNATCH);
proc_spl_kmem_slab->proc_fops = &proc_slab_operations;
#endif /* DEBUG_KMEM */
-#ifdef DEBUG_KSTAT
proc_spl_kstat = proc_mkdir("kstat", proc_spl);
if (proc_spl_kstat == NULL)
GOTO(out, rc = -EUNATCH);
-#endif /* DEBUG_KSTAT */
-
out:
if (rc) {
remove_proc_entry("kstat", proc_spl);
#ifdef DEBUG_KMEM
remove_proc_entry("slab", proc_spl_kmem);
-#endif
remove_proc_entry("kmem", proc_spl);
+#endif
remove_proc_entry("spl", NULL);
#ifdef CONFIG_SYSCTL
spl_unregister_sysctl_table(spl_header);
#endif /* CONFIG_SYSCTL */
}
-#endif /* DEBUG_KMEM || DEBUG_KSTAT */
RETURN(rc);
}
{
ENTRY;
-#if defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
remove_proc_entry("kstat", proc_spl);
#ifdef DEBUG_KMEM
remove_proc_entry("slab", proc_spl_kmem);
-#endif
remove_proc_entry("kmem", proc_spl);
+#endif
remove_proc_entry("spl", NULL);
-#endif /* DEBUG_KMEM || DEBUG_KSTAT */
#ifdef CONFIG_SYSCTL
ASSERT(spl_header != NULL);
/* Atomic types use spinlocks */
#undef ATOMIC_SPINLOCK
-/* Define to 1 to enable callb debugging */
-#undef DEBUG_CALLB
-
-/* Define to 1 to enable kmem debugging */
+/* Define to 1 to enable basic kmem accounting */
#undef DEBUG_KMEM
-/* Define to 1 to enable kstat debugging */
-#undef DEBUG_KSTAT
+/* Define to 1 to enable detailed kmem tracking */
+#undef DEBUG_KMEM_TRACKING
/* register_sysctl_table() wants 2 args */
#undef HAVE_2ARGS_REGISTER_SYSCTL