New sysctl

Link to this paste: http://bugs.dragonflybsd.org/pastes/5

Added by tuxillo almost 3 years ago.
Syntax: Diff

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
diff --git a/sys/kern/kern_slaballoc.c b/sys/kern/kern_slaballoc.c
index 747ecc3..5deb71e 100644
--- a/sys/kern/kern_slaballoc.c
+++ b/sys/kern/kern_slaballoc.c
@@ -160,6 +160,7 @@ static int32_t weirdary[16];

 static void *kmem_slab_alloc(vm_size_t bytes, vm_offset_t align, int flags);
 static void kmem_slab_free(void *ptr, vm_size_t bytes);
+static int sysctl_kern_memstats(SYSCTL_HANDLER_ARGS);

 #if defined(INVARIANTS)
 static void chunk_mark_allocated(SLZone *z, void *chunk);
@@ -222,11 +223,71 @@ SYSCTL_INT(_debug, OID_AUTO, use_malloc_pattern, CTLFLAG_RW,
     "Initialize memory to -1 if M_ZERO not specified");
 #endif

+SYSCTL_OID(_kern, OID_AUTO, memstats, CTLTYPE_STRING|CTLFLAG_RD, \
+    NULL, 0, sysctl_kern_memstats, "A", "Malloc types info");
+
 static int ZoneRelsThresh = ZONE_RELS_THRESH;
 SYSCTL_INT(_kern, OID_AUTO, zone_big_alloc, CTLFLAG_RD, &ZoneBigAlloc, 0, "");
 SYSCTL_INT(_kern, OID_AUTO, zone_gen_alloc, CTLFLAG_RD, &ZoneGenAlloc, 0, "");
 SYSCTL_INT(_kern, OID_AUTO, zone_cache, CTLFLAG_RW, &ZoneRelsThresh, 0, "");

+static int
+sysctl_kern_memstats(SYSCTL_HANDLER_ARGS)
+{
+       struct malloc_type *cur;
+       char tmpbuf[256];
+       size_t allocs;
+       size_t totuse;
+       int64_t totreq;
+       size_t meminuse;
+       size_t calls;
+       int error;
+       int cpu;
+
+       totuse = 0;
+       totreq = 0;
+
+       ksnprintf(tmpbuf, sizeof(tmpbuf),
+           "\n           Type      InUse   MemUse    HighUse      Limit  Requests\n");
+       error = SYSCTL_OUT(req, tmpbuf, strlen(tmpbuf));
+       if (error)
+               return (error);
+
+       for (cur = kmemstatistics; cur != NULL; cur = cur->ks_next) {
+
+               /* Per-cpu values must be aggregated */
+               meminuse = 0;
+               allocs = 0;
+               calls = 0;
+               for (cpu = allocs = meminuse = 0; cpu < SMP_MAXCPU; cpu++) {
+                       allocs += cur->ks_inuse[cpu];
+                       meminuse += cur->ks_memuse[cpu];
+                       calls += cur->ks_calls[cpu];
+                       totuse += cur->ks_memuse[cpu];
+                       totreq += cur->ks_calls[cpu];
+               }
+
+               ksnprintf(tmpbuf, sizeof(tmpbuf), "%19s %6ld %7ldK %9ldK %9zdK %9jd\n",
+                   cur->ks_shortdesc, allocs, (meminuse + 1023) / 1024,
+                   (cur->ks_maxused + 1023) / 1024,
+                   (cur->ks_limit + 1023) / 1024, (intmax_t)calls);
+
+               error = SYSCTL_OUT(req, tmpbuf, strlen(tmpbuf));
+               if (error)
+                       return (error);
+
+       }
+
+       ksnprintf(tmpbuf, sizeof(tmpbuf), "\nMemory Totals:  In Use     Requests\n"
+           "              %7ldK     %8ld\n", (totuse + 1023) / 1024, totreq);
+
+       error = SYSCTL_OUT(req, tmpbuf, strlen(tmpbuf));
+       if (error)
+               return (error);
+
+       return 0;
+}
+
 /*
  * Returns the kernel memory size limit for the purposes of initializing
  * various subsystem caches.  The smaller of available memory and the KVM
@@ -544,7 +605,7 @@ kmalloc(unsigned long size, struct malloc_type *type, int flags)
            malloc_init(type);
        crit_exit();
     }
-    ++type->ks_calls;
+    ++type->ks_calls[gd->gd_cpuid];

     /*
      * Handle the case where the limit is reached.  Panic if we can't return

Download