Page MenuHomeFreeBSD

D40575.diff
No OneTemporary

D40575.diff

diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -107,6 +107,11 @@
static struct rwlock_padalign vm_phys_fictitious_reg_lock;
MALLOC_DEFINE(M_FICT_PAGES, "vm_fictitious", "Fictitious VM pages");
+struct vm_phys_info {
+ uint64_t free_pages;
+ uint64_t free_blocks;
+};
+
static struct vm_freelist __aligned(CACHE_LINE_SIZE)
vm_phys_free_queues[MAXMEMDOM][VM_NFREELIST][VM_NFREEPOOL]
[VM_NFREEORDER_MAX];
@@ -156,6 +161,11 @@
sysctl_vm_phys_free, "A",
"Phys Free Info");
+static int sysctl_vm_phys_frag_idx(SYSCTL_HANDLER_ARGS);
+SYSCTL_OID(_vm, OID_AUTO, phys_frag_idx,
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_vm_phys_frag_idx, "A", "Phys Frag Info");
+
static int sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS);
SYSCTL_OID(_vm, OID_AUTO, phys_segs,
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
@@ -291,6 +301,78 @@
return (error);
}
+static void
+vm_phys_get_info(struct vm_phys_info *info, int domain)
+{
+ struct vm_freelist *fl;
+ int pind, oind, flind;
+
+ /* Calculate total number of free pages and blocks */
+ info->free_pages = info->free_blocks = 0;
+ for (flind = 0; flind < vm_nfreelists; flind++) {
+ for (oind = VM_NFREEORDER - 1; oind >= 0; oind--) {
+ for (pind = 0; pind < VM_NFREEPOOL; pind++) {
+ fl = vm_phys_free_queues[domain][flind][pind];
+ info->free_pages += fl[oind].lcnt << oind;
+ info->free_blocks += fl[oind].lcnt;
+ }
+ }
+ }
+}
+
+static int
+vm_phys_fragmentation_index(int order, int domain)
+{
+ struct vm_phys_info info;
+
+ vm_domain_free_assert_locked(VM_DOMAIN(domain));
+ vm_phys_get_info(&info, domain);
+
+ if (info.free_blocks == 0) {
+ return (0);
+ }
+
+ return (1000 -
+ ((info.free_pages * 1000) / (1 << order) / info.free_blocks));
+}
+
+/*
+ * Outputs the value of the Free Memory Fragmentation Index (FMFI) for each
+ * domain.
+ */
+static int
+sysctl_vm_phys_frag_idx(SYSCTL_HANDLER_ARGS)
+{
+ struct sbuf sbuf;
+ int64_t idx;
+ int oind, dom, error;
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+ sbuf_new_for_sysctl(&sbuf, NULL, 128 * vm_ndomains, req);
+
+ for (dom = 0; dom < vm_ndomains; dom++) {
+
+ sbuf_printf(&sbuf, "\nDOMAIN %d\n", dom);
+ sbuf_printf(&sbuf, "\n ORDER (SIZE) | FMFI\n");
+ sbuf_printf(&sbuf, "--\n");
+
+ vm_domain_free_lock(VM_DOMAIN(dom));
+ for (oind = VM_NFREEORDER - 1; oind >= 0; oind--) {
+ idx = vm_phys_fragmentation_index(oind, dom);
+ sbuf_printf(&sbuf, " %2d (%6dK) ", oind,
+ 1 << (PAGE_SHIFT - 10 + oind));
+ sbuf_printf(&sbuf, "| %ld \n", idx);
+ }
+ vm_domain_free_unlock(VM_DOMAIN(dom));
+ }
+
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ return (error);
+}
+
/*
* Outputs the set of physical memory segments.
*/

File Metadata

Mime Type
text/plain
Expires
Fri, May 15, 11:56 AM (16 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33082697
Default Alt Text
D40575.diff (2 KB)

Event Timeline