]> git.proxmox.com Git - mirror_spl-debian.git/commitdiff
Add slab usage summeries to /proc
authorBrian Behlendorf <behlendorf1@llnl.gov>
Sat, 26 Mar 2011 07:03:32 +0000 (00:03 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 7 Apr 2011 03:06:03 +0000 (20:06 -0700)
One of the most common things you want to know when looking at
the slab is how much memory is being used.  This information was
available in /proc/spl/kmem/slab but only on a per-slab basis.
This commit adds the following /proc/sys/kernel/spl/kmem/slab*
entries to make total slab usage easily available at a glance.

  slab_kmem_total - Total kmem slab size
  slab_kmem_avail - Alloc'd kmem slab size
  slab_kmem_max   - Max observed kmem slab size
  slab_vmem_total - Total vmem slab size
  slab_vmem_avail - Alloc'd vmem slab size
  slab_vmem_max   - Max observed vmem slab size

NOTE: The slab_*_max values are expected to over report because
they show maximum values since boot, not current values.

include/sys/kmem.h
module/spl/spl-proc.c

index 6b6b95c12e3192439af144aa549b3d8ef8933ca2..d3972f1ca701c8700dd98e3757d8aeca8e6b1373 100644 (file)
@@ -293,6 +293,9 @@ enum {
        KMC_BIT_OFFSLAB         = 7,    /* Objects not on slab */
        KMC_BIT_REAPING         = 16,   /* Reaping in progress */
        KMC_BIT_DESTROY         = 17,   /* Destroy in progress */
+       KMC_BIT_TOTAL           = 18,   /* Proc handler helper bit */
+       KMC_BIT_ALLOC           = 19,   /* Proc handler helper bit */
+       KMC_BIT_MAX             = 20,   /* Proc handler helper bit */
 };
 
 /* kmem move callback return values */
@@ -314,6 +317,9 @@ typedef enum kmem_cbrc {
 #define KMC_OFFSLAB            (1 << KMC_BIT_OFFSLAB)
 #define KMC_REAPING            (1 << KMC_BIT_REAPING)
 #define KMC_DESTROY            (1 << KMC_BIT_DESTROY)
+#define KMC_TOTAL              (1 << KMC_BIT_TOTAL)
+#define KMC_ALLOC              (1 << KMC_BIT_ALLOC)
+#define KMC_MAX                        (1 << KMC_BIT_MAX)
 
 #define KMC_REAP_CHUNK                 INT_MAX
 #define KMC_DEFAULT_SEEKS              1
index 39b65ff3875451efe8306b31532d9a7b0315119a..d2b295ce0aff46a4f37b110a4da5eb3ffdb49e76 100644 (file)
@@ -100,7 +100,12 @@ struct proc_dir_entry *proc_spl_kstat = NULL;
 #define CTL_KMEM_KMEMMAX       CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
 #define CTL_KMEM_VMEMUSED      CTL_UNNUMBERED /* Alloc'd vmem bytes */
 #define CTL_KMEM_VMEMMAX       CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
-#define CTL_KMEM_ALLOC_FAILED  CTL_UNNUMBERED /* Cache allocations failed */
+#define CTL_KMEM_SLAB_KMEMTOTAL        CTL_UNNUMBERED /* Total kmem slab size */
+#define CTL_KMEM_SLAB_KMEMALLOC        CTL_UNNUMBERED /* Alloc'd kmem slab size */
+#define CTL_KMEM_SLAB_KMEMMAX  CTL_UNNUMBERED /* Max kmem slab size */
+#define CTL_KMEM_SLAB_VMEMTOTAL        CTL_UNNUMBERED /* Total vmem slab size */
+#define CTL_KMEM_SLAB_VMEMALLOC        CTL_UNNUMBERED /* Alloc'd vmem slab size */
+#define CTL_KMEM_SLAB_VMEMMAX  CTL_UNNUMBERED /* Max vmem slab size */
 #endif
 
 #else /* HAVE_CTL_UNNUMBERED */
@@ -152,6 +157,12 @@ enum {
        CTL_KMEM_KMEMMAX,               /* Max alloc'd by kmem bytes */
        CTL_KMEM_VMEMUSED,              /* Alloc'd vmem bytes */
        CTL_KMEM_VMEMMAX,               /* Max alloc'd by vmem bytes */
+       CTL_KMEM_SLAB_KMEMTOTAL,        /* Total kmem slab size */
+       CTL_KMEM_SLAB_KMEMALLOC,        /* Alloc'd kmem slab size */
+       CTL_KMEM_SLAB_KMEMMAX,          /* Max kmem slab size */
+       CTL_KMEM_SLAB_VMEMTOTAL,        /* Total vmem slab size */
+       CTL_KMEM_SLAB_VMEMALLOC,        /* Alloc'd vmem slab size */
+       CTL_KMEM_SLAB_VMEMMAX,          /* Max vmem slab size */
 #endif
 };
 #endif /* HAVE_CTL_UNNUMBERED */
@@ -424,6 +435,53 @@ SPL_PROC_HANDLER(proc_domemused)
 
         SRETURN(rc);
 }
+
+SPL_PROC_HANDLER(proc_doslab)
+{
+        int rc = 0;
+        unsigned long min = 0, max = ~0, val = 0, mask;
+        struct ctl_table dummy = *table;
+        spl_kmem_cache_t *skc;
+        SENTRY;
+
+        dummy.data = &val;
+        dummy.proc_handler = &proc_dointvec;
+        dummy.extra1 = &min;
+        dummy.extra2 = &max;
+
+        if (write) {
+                *ppos += *lenp;
+        } else {
+                down_read(&spl_kmem_cache_sem);
+                mask = (unsigned long)table->data;
+
+                list_for_each_entry(skc, &spl_kmem_cache_list, skc_list) {
+
+                       /* Only use slabs of the correct kmem/vmem type */
+                       if (!(skc->skc_flags & mask))
+                               continue;
+
+                       /* Sum the specified field for selected slabs */
+                       switch (mask & (KMC_TOTAL | KMC_ALLOC | KMC_MAX)) {
+                       case KMC_TOTAL:
+                               val += skc->skc_slab_size * skc->skc_slab_total;
+                               break;
+                       case KMC_ALLOC:
+                               val += skc->skc_obj_size * skc->skc_obj_alloc;
+                               break;
+                       case KMC_MAX:
+                               val += skc->skc_obj_size * skc->skc_obj_max;
+                               break;
+                       }
+                }
+
+                up_read(&spl_kmem_cache_sem);
+                rc = spl_proc_doulongvec_minmax(&dummy, write, filp,
+                                                buffer, lenp, ppos);
+        }
+
+        SRETURN(rc);
+}
 #endif /* DEBUG_KMEM */
 
 SPL_PROC_HANDLER(proc_dohostid)
@@ -895,6 +953,66 @@ static struct ctl_table spl_kmem_table[] = {
                 .mode     = 0444,
                 .proc_handler = &proc_doulongvec_minmax,
         },
+        {
+                CTL_NAME    (CTL_KMEM_SLAB_KMEMTOTAL)
+                .procname = "slab_kmem_total",
+               .data     = (void *)(KMC_KMEM | KMC_TOTAL),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                CTL_NAME    (CTL_KMEM_SLAB_KMEMALLOC)
+                .procname = "slab_kmem_alloc",
+               .data     = (void *)(KMC_KMEM | KMC_ALLOC),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                CTL_NAME    (CTL_KMEM_SLAB_KMEMMAX)
+                .procname = "slab_kmem_max",
+               .data     = (void *)(KMC_KMEM | KMC_MAX),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                CTL_NAME    (CTL_KMEM_SLAB_VMEMTOTAL)
+                .procname = "slab_vmem_total",
+               .data     = (void *)(KMC_VMEM | KMC_TOTAL),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                CTL_NAME    (CTL_KMEM_SLAB_VMEMALLOC)
+                .procname = "slab_vmem_alloc",
+               .data     = (void *)(KMC_VMEM | KMC_ALLOC),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                CTL_NAME    (CTL_KMEM_SLAB_VMEMMAX)
+                .procname = "slab_vmem_max",
+               .data     = (void *)(KMC_VMEM | KMC_MAX),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
        {0},
 };
 #endif /* DEBUG_KMEM */