Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150777545
D27026.id78999.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D27026.id78999.diff
View Options
Index: lib/libmemstat/memstat.h
===================================================================
--- lib/libmemstat/memstat.h
+++ lib/libmemstat/memstat.h
@@ -117,6 +117,13 @@
int memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle);
int memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle);
+/*
+ * General malloc routines.
+ */
+size_t memstat_malloc_zone_get_count(void);
+size_t memstat_malloc_zone_get_size(size_t n);
+int memstat_malloc_zone_used(const struct memory_type *mtp, size_t n);
+
/*
* Accessor methods for struct memory_type.
*/
Index: lib/libmemstat/memstat_malloc.c
===================================================================
--- lib/libmemstat/memstat_malloc.c
+++ lib/libmemstat/memstat_malloc.c
@@ -44,10 +44,22 @@
#include "memstat.h"
#include "memstat_internal.h"
+static int memstat_malloc_zone_count;
+static int memstat_malloc_zone_sizes[32];
+
+static int memstat_malloc_zone_init(void);
+static int memstat_malloc_zone_init_kvm(kvm_t *kvm);
+
static struct nlist namelist[] = {
#define X_KMEMSTATISTICS 0
{ .n_name = "_kmemstatistics" },
-#define X_MP_MAXCPUS 1
+#define X_KMEMZONES 1
+ { .n_name = "_kmemzones" },
+#define X_NUMZONES 2
+ { .n_name = "_numzones" },
+#define X_VM_MALLOC_ZONE_COUNT 3
+ { .n_name = "_vm_malloc_zone_count" },
+#define X_MP_MAXCPUS 4
{ .n_name = "_mp_maxcpus" },
{ .n_name = "" },
};
@@ -111,6 +123,11 @@
return (-1);
}
+ if (memstat_malloc_zone_init() == -1) {
+ list->mtl_error = MEMSTAT_ERROR_VERSION;
+ return (-1);
+ }
+
size = sizeof(*mthp) + count * (sizeof(*mthp) + sizeof(*mtsp) *
maxcpus);
@@ -333,6 +350,12 @@
return (-1);
}
+ ret = memstat_malloc_zone_init_kvm(kvm);
+ if (ret != 0) {
+ list->mtl_error = ret;
+ return (-1);
+ }
+
mp_ncpus = kvm_getncpus(kvm);
for (typep = kmemstatistics; typep != NULL; typep = type.ks_next) {
@@ -416,3 +439,107 @@
return (0);
}
+
+static int
+memstat_malloc_zone_init(void)
+{
+ size_t size;
+
+ size = sizeof(memstat_malloc_zone_count);
+ if (sysctlbyname("vm.malloc.zone_count", &memstat_malloc_zone_count, &size, NULL, 0) < 0) {
+ return (-1);
+ }
+
+ if (memstat_malloc_zone_count > (int)nitems(memstat_malloc_zone_sizes)) {
+ return (-1);
+ }
+
+ size = sizeof(memstat_malloc_zone_sizes);
+ if (sysctlbyname("vm.malloc.zone_sizes", &memstat_malloc_zone_sizes, &size, NULL, 0) < 0) {
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Copied from kern_malloc.c
+ *
+ * kz_zone is an array sized at compilation time, the size is exported in
+ * "numzones". Below we need to iterate kz_size.
+ */
+struct memstat_kmemzone {
+ int kz_size;
+ const char *kz_name;
+ void *kz_zone[1];
+};
+
+static int
+memstat_malloc_zone_init_kvm(kvm_t *kvm)
+{
+ struct memstat_kmemzone *kmemzones, *kz;
+ int numzones, objsize, allocsize, ret;
+ int i;
+
+ ret = kread_symbol(kvm, X_VM_MALLOC_ZONE_COUNT,
+ &memstat_malloc_zone_count, sizeof(memstat_malloc_zone_count), 0);
+ if (ret != 0) {
+ return (ret);
+ }
+
+ ret = kread_symbol(kvm, X_NUMZONES, &numzones, sizeof(numzones), 0);
+ if (ret != 0) {
+ return (ret);
+ }
+
+ objsize = __offsetof(struct memstat_kmemzone, kz_zone) +
+ sizeof(void *) * numzones;
+
+ allocsize = objsize * memstat_malloc_zone_count;
+ kmemzones = malloc(allocsize);
+ if (kmemzones == NULL) {
+ return (MEMSTAT_ERROR_NOMEMORY);
+ }
+ ret = kread_symbol(kvm, X_KMEMZONES, kmemzones, allocsize, 0);
+ if (ret != 0) {
+ free(kmemzones);
+ return (ret);
+ }
+
+ kz = kmemzones;
+ for (i = 0; i < (int)nitems(memstat_malloc_zone_sizes); i++) {
+ memstat_malloc_zone_sizes[i] = kz->kz_size;
+ kz = (struct memstat_kmemzone *)((char *)kz + objsize);
+ }
+
+ free(kmemzones);
+ return (0);
+}
+
+size_t
+memstat_malloc_zone_get_count(void)
+{
+
+ return (memstat_malloc_zone_count);
+}
+
+size_t
+memstat_malloc_zone_get_size(size_t n)
+{
+
+ if (n >= nitems(memstat_malloc_zone_sizes)) {
+ return (-1);
+ }
+
+ return (memstat_malloc_zone_sizes[n]);
+}
+
+int
+memstat_malloc_zone_used(const struct memory_type *mtp, size_t n)
+{
+
+ if (memstat_get_sizemask(mtp) & (1 << n))
+ return (1);
+
+ return (0);
+}
Index: sys/kern/kern_malloc.c
===================================================================
--- sys/kern/kern_malloc.c
+++ sys/kern/kern_malloc.c
@@ -147,6 +147,8 @@
* Small malloc(9) memory allocations are allocated from a set of UMA buckets
* of various sizes.
*
+ * Warning: the layout of the struct is duplicated in libmemstat for KVM support.
+ *
* XXX: The comment here used to read "These won't be powers of two for
* long." It's possible that a significant amount of wasted memory could be
* recovered by tuning the sizes of these buckets.
@@ -217,6 +219,19 @@
CTLFLAG_RD | CTLTYPE_ULONG | CTLFLAG_MPSAFE, NULL, 0,
sysctl_kmem_map_free, "LU", "Free space in kmem");
+static SYSCTL_NODE(_vm, OID_AUTO, malloc, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
+ "Malloc information");
+
+static u_int vm_malloc_zone_count = nitems(kmemzones);
+SYSCTL_UINT(_vm_malloc, OID_AUTO, zone_count,
+ CTLFLAG_RD, &vm_malloc_zone_count, 0,
+ "Number of malloc zones");
+
+static int sysctl_vm_malloc_zone_sizes(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_vm_malloc, OID_AUTO, zone_sizes,
+ CTLFLAG_RD | CTLTYPE_OPAQUE | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_vm_malloc_zone_sizes, "S", "Zone sizes used by malloc");
+
/*
* The malloc_mtx protects the kmemstatistics linked list.
*/
@@ -278,6 +293,19 @@
return (sysctl_handle_long(oidp, &size, 0, req));
}
+static int
+sysctl_vm_malloc_zone_sizes(SYSCTL_HANDLER_ARGS)
+{
+ int sizes[nitems(kmemzones)];
+ int i;
+
+ for (i = 0; i < nitems(kmemzones); i++) {
+ sizes[i] = kmemzones[i].kz_size;
+ }
+
+ return (SYSCTL_OUT(req, &sizes, sizeof(sizes)));
+}
+
/*
* malloc(9) uma zone separation -- sub-page buffer overruns in one
* malloc type will affect only a subset of other malloc types.
Index: usr.bin/vmstat/vmstat.c
===================================================================
--- usr.bin/vmstat/vmstat.c
+++ usr.bin/vmstat/vmstat.c
@@ -1407,7 +1407,8 @@
{
struct memory_type_list *mtlp;
struct memory_type *mtp;
- int error, first, i;
+ size_t i, zones;
+ int error, first;
mtlp = memstat_mtl_alloc();
if (mtlp == NULL) {
@@ -1435,6 +1436,7 @@
xo_emit("{T:/%13s} {T:/%5s} {T:/%6s} {T:/%7s} {T:/%8s} {T:Size(s)}\n",
"Type", "InUse", "MemUse", "HighUse", "Requests");
xo_open_list("memory");
+ zones = memstat_malloc_zone_get_count();
for (mtp = memstat_mtl_first(mtlp); mtp != NULL;
mtp = memstat_mtl_next(mtp)) {
if (memstat_get_numallocs(mtp) == 0 &&
@@ -1449,11 +1451,11 @@
(uintmax_t)memstat_get_numallocs(mtp));
first = 1;
xo_open_list("size");
- for (i = 0; i < 32; i++) {
- if (memstat_get_sizemask(mtp) & (1 << i)) {
+ for (i = 0; i < zones; i++) {
+ if (memstat_malloc_zone_used(mtp, i)) {
if (!first)
xo_emit(",");
- xo_emit("{l:size/%d}", 1 << (i + 4));
+ xo_emit("{l:size/%d}", memstat_malloc_zone_get_size(i));
first = 0;
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 5, 12:01 AM (14 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30853907
Default Alt Text
D27026.id78999.diff (6 KB)
Attached To
Mode
D27026: Export kernel malloc sizes
Attached
Detach File
Event Timeline
Log In to Comment