Default to --disable-debug-kmem

The default kmem debugging (--enable-debug-kmem) can severely impact
performance on large-scale NUMA systems due to the atomic operations
used in the memory accounting. A 32-thread fio test running on a
40-core 80-thread system and performing 100% cached reads with kmem
debugging is:

Enabled:
READ: io=177071MB, aggrb=2951.2MB/s, minb=2951.2MB/s, maxb=2951.2MB/s,

Disabled:
READ: io=271454MB, aggrb=4524.4MB/s, minb=4524.4MB/s, maxb=4524.4MB/s,

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tim Chase <tim@chase2k.com>
Issues #463
This commit is contained in:
Brian Behlendorf 2015-07-20 12:18:56 -07:00
parent 37d7cd94f3
commit 9eb361aaa5
2 changed files with 6 additions and 22 deletions

View File

@ -452,15 +452,14 @@ dnl #
dnl # Enabled by default it provides a minimal level of memory tracking. 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 # 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 # 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 # if memory was leaked.
dnl # and provide an easy way to inspect the kmem based slab.
dnl # dnl #
AC_DEFUN([SPL_AC_DEBUG_KMEM], [ AC_DEFUN([SPL_AC_DEBUG_KMEM], [
AC_ARG_ENABLE([debug-kmem], AC_ARG_ENABLE([debug-kmem],
[AS_HELP_STRING([--enable-debug-kmem], [AS_HELP_STRING([--enable-debug-kmem],
[Enable basic kmem accounting @<:@default=yes@:>@])], [Enable basic kmem accounting @<:@default=no@:>@])],
[], [],
[enable_debug_kmem=yes]) [enable_debug_kmem=no])
AS_IF([test "x$enable_debug_kmem" = xyes], AS_IF([test "x$enable_debug_kmem" = xyes],
[ [

View File

@ -42,17 +42,13 @@ typedef struct ctl_table __no_const spl_ctl_table;
typedef struct ctl_table spl_ctl_table; typedef struct ctl_table spl_ctl_table;
#endif #endif
#ifdef DEBUG_KMEM
static unsigned long table_min = 0; static unsigned long table_min = 0;
static unsigned long table_max = ~0; static unsigned long table_max = ~0;
#endif
static struct ctl_table_header *spl_header = NULL; static struct ctl_table_header *spl_header = NULL;
static struct proc_dir_entry *proc_spl = NULL; 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 = NULL;
static struct proc_dir_entry *proc_spl_kmem_slab = NULL; static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
#endif /* DEBUG_KMEM */
struct proc_dir_entry *proc_spl_kstat = NULL; struct proc_dir_entry *proc_spl_kstat = NULL;
static int static int
@ -135,6 +131,7 @@ proc_domemused(struct ctl_table *table, int write,
return (rc); return (rc);
} }
#endif /* DEBUG_KMEM */
static int static int
proc_doslab(struct ctl_table *table, int write, proc_doslab(struct ctl_table *table, int write,
@ -182,7 +179,6 @@ proc_doslab(struct ctl_table *table, int write,
return (rc); return (rc);
} }
#endif /* DEBUG_KMEM */
static int static int
proc_dohostid(struct ctl_table *table, int write, proc_dohostid(struct ctl_table *table, int write,
@ -219,7 +215,6 @@ proc_dohostid(struct ctl_table *table, int write,
return (rc); return (rc);
} }
#ifdef DEBUG_KMEM
static void static void
slab_seq_show_headers(struct seq_file *f) slab_seq_show_headers(struct seq_file *f)
{ {
@ -329,10 +324,9 @@ static struct file_operations proc_slab_operations = {
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .release = seq_release,
}; };
#endif /* DEBUG_KMEM */
#ifdef DEBUG_KMEM
static struct ctl_table spl_kmem_table[] = { static struct ctl_table spl_kmem_table[] = {
#ifdef DEBUG_KMEM
{ {
.procname = "kmem_used", .procname = "kmem_used",
.data = &kmem_alloc_used, .data = &kmem_alloc_used,
@ -353,6 +347,7 @@ static struct ctl_table spl_kmem_table[] = {
.mode = 0444, .mode = 0444,
.proc_handler = &proc_doulongvec_minmax, .proc_handler = &proc_doulongvec_minmax,
}, },
#endif /* DEBUG_KMEM */
{ {
.procname = "slab_kmem_total", .procname = "slab_kmem_total",
.data = (void *)(KMC_KMEM | KMC_TOTAL), .data = (void *)(KMC_KMEM | KMC_TOTAL),
@ -409,7 +404,6 @@ static struct ctl_table spl_kmem_table[] = {
}, },
{0}, {0},
}; };
#endif /* DEBUG_KMEM */
static struct ctl_table spl_kstat_table[] = { static struct ctl_table spl_kstat_table[] = {
{0}, {0},
@ -433,13 +427,11 @@ static struct ctl_table spl_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dohostid, .proc_handler = &proc_dohostid,
}, },
#ifdef DEBUG_KMEM
{ {
.procname = "kmem", .procname = "kmem",
.mode = 0555, .mode = 0555,
.child = spl_kmem_table, .child = spl_kmem_table,
}, },
#endif
{ {
.procname = "kstat", .procname = "kstat",
.mode = 0555, .mode = 0555,
@ -484,7 +476,6 @@ spl_proc_init(void)
goto out; goto out;
} }
#ifdef DEBUG_KMEM
proc_spl_kmem = proc_mkdir("kmem", proc_spl); proc_spl_kmem = proc_mkdir("kmem", proc_spl);
if (proc_spl_kmem == NULL) { if (proc_spl_kmem == NULL) {
rc = -EUNATCH; rc = -EUNATCH;
@ -498,8 +489,6 @@ spl_proc_init(void)
goto out; goto out;
} }
#endif /* DEBUG_KMEM */
proc_spl_kstat = proc_mkdir("kstat", proc_spl); proc_spl_kstat = proc_mkdir("kstat", proc_spl);
if (proc_spl_kstat == NULL) { if (proc_spl_kstat == NULL) {
rc = -EUNATCH; rc = -EUNATCH;
@ -508,10 +497,8 @@ spl_proc_init(void)
out: out:
if (rc) { if (rc) {
remove_proc_entry("kstat", proc_spl); remove_proc_entry("kstat", proc_spl);
#ifdef DEBUG_KMEM
remove_proc_entry("slab", proc_spl_kmem); remove_proc_entry("slab", proc_spl_kmem);
remove_proc_entry("kmem", proc_spl); remove_proc_entry("kmem", proc_spl);
#endif
remove_proc_entry("spl", NULL); remove_proc_entry("spl", NULL);
unregister_sysctl_table(spl_header); unregister_sysctl_table(spl_header);
} }
@ -523,10 +510,8 @@ void
spl_proc_fini(void) spl_proc_fini(void)
{ {
remove_proc_entry("kstat", proc_spl); remove_proc_entry("kstat", proc_spl);
#ifdef DEBUG_KMEM
remove_proc_entry("slab", proc_spl_kmem); remove_proc_entry("slab", proc_spl_kmem);
remove_proc_entry("kmem", proc_spl); remove_proc_entry("kmem", proc_spl);
#endif
remove_proc_entry("spl", NULL); remove_proc_entry("spl", NULL);
ASSERT(spl_header != NULL); ASSERT(spl_header != NULL);