kern.memstats
Link to this paste: http://bugs.dragonflybsd.org/pastes/6
Added by tuxillo over 1 year 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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
diff --git a/sys/kern/kern_slaballoc.c b/sys/kern/kern_slaballoc.c index 747ecc3..d7ca4e7 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 diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h index 4a4895c..46a8597 100644 --- a/sys/sys/malloc.h +++ b/sys/sys/malloc.h @@ -109,16 +109,13 @@ struct malloc_type { struct malloc_type *ks_next; /* next in list */ size_t ks_memuse[SMP_MAXCPU]; /* total memory held in bytes */ size_t ks_loosememuse; /* (inaccurate) aggregate memuse */ - size_t ks_limit; /* most that are allowed to exist */ - long ks_size; /* sizes of this thing that are allocated */ - size_t ks_inuse[SMP_MAXCPU]; /* # of allocs currently in use */ - __int64_t ks_calls; /* total packets of this type ever allocated */ - long ks_maxused; /* maximum number ever used */ - __uint32_t ks_magic; /* if it's not magic, don't touch it */ + size_t ks_limit; /* most that are allowed to exist */ + long ks_size; /* sizes of this thing that are allocated */ + size_t ks_inuse[SMP_MAXCPU]; /* # of allocs currently in use */ + __int64_t ks_calls[SMP_MAXCPU]; /* per-cpu total packets of this type ever allocated */ + long ks_maxused; /* maximum number ever used */ + __uint32_t ks_magic; /* if it's not magic, don't touch it */ const char *ks_shortdesc; /* short description */ - __uint16_t ks_limblocks; /* number of times blocked for hitting limit */ - __uint16_t ks_mapblocks; /* number of times blocked for kernel map */ - long ks_reserved[4]; /* future use (module compatibility) */ }; typedef struct malloc_type *malloc_type_t; @@ -127,7 +124,7 @@ typedef struct malloc_type *malloc_type_t; #define MALLOC_DEFINE(type, shortdesc, longdesc) \ struct malloc_type type[1] = { \ - { NULL, { 0 }, 0, 0, 0, { 0 }, 0, 0, M_MAGIC, shortdesc, 0, 0, { 0 } } \ + { NULL, { 0 }, 0, 0, 0, { 0 }, { 0 }, 0, M_MAGIC, shortdesc } \ }; \ SYSINIT(type##_init, SI_BOOT1_KMALLOC, SI_ORDER_ANY, malloc_init, type); \ SYSUNINIT(type##_uninit, SI_BOOT1_KMALLOC, SI_ORDER_ANY, malloc_uninit, type) @@ -136,7 +133,7 @@ typedef struct malloc_type *malloc_type_t; #define MALLOC_DEFINE(type, shortdesc, longdesc) \ struct malloc_type type[1] = { \ - { NULL, { 0 }, 0, 0, 0, { 0 }, 0, 0, M_MAGIC, shortdesc, 0, 0 } \ + { NULL, { 0 }, 0, 0, 0, { 0 }, { 0 }, 0, M_MAGIC, shortdesc } \ }; #endif |