summaryrefslogtreecommitdiffstats
path: root/lib/libkvm/kvm_proc.c
diff options
context:
space:
mode:
authorstefan <stefan@openbsd.org>2016-05-22 16:18:26 +0000
committerstefan <stefan@openbsd.org>2016-05-22 16:18:26 +0000
commit3278328672470970abc667b99bed30fa18aee159 (patch)
treeaa71afc6f132387fece89cee9a0cd84b707f0e6b /lib/libkvm/kvm_proc.c
parentUse the -F flag of install(1) to ensure the file's content is flushed to disk. (diff)
downloadwireguard-openbsd-3278328672470970abc667b99bed30fa18aee159.tar.xz
wireguard-openbsd-3278328672470970abc667b99bed30fa18aee159.zip
Make amaps use less kernel memory
This is achieved by grouping amap slots into chunks that are allocated on-demand by pool(9). Endless "fltamapcopy" loops because of kmem shortage should be solved now. The kmem savings are also important to later enable vmm(4) to use larged shared memory mappings for guest VM RAM. This adapts libkvm also because the amap structure layout has changed. Testing and fix of libkvm glitch in initial diff by tb@ Feedback and "time to get this in" kettenis@
Diffstat (limited to 'lib/libkvm/kvm_proc.c')
-rw-r--r--lib/libkvm/kvm_proc.c64
1 files changed, 53 insertions, 11 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index a9b466591ef..bec8b775d77 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_proc.c,v 1.53 2016/05/11 17:46:44 tedu Exp $ */
+/* $OpenBSD: kvm_proc.c,v 1.54 2016/05/22 16:18:26 stefan Exp $ */
/* $NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -108,6 +108,56 @@ static int proc_verify(kvm_t *, const struct kinfo_proc *);
static void ps_str_a(struct ps_strings *, u_long *, int *);
static void ps_str_e(struct ps_strings *, u_long *, int *);
+static struct vm_anon *
+_kvm_findanon(kvm_t *kd, struct vm_amap *amapp, int slot)
+{
+ u_long addr;
+ int bucket;
+ struct vm_amap amap;
+ struct vm_amap_chunk chunk, *chunkp;
+ struct vm_anon *anonp;
+
+ addr = (u_long)amapp;
+ if (KREAD(kd, addr, &amap))
+ return (NULL);
+
+ /* sanity-check slot number */
+ if (slot > amap.am_nslot)
+ return (NULL);
+
+ if (UVM_AMAP_SMALL(&amap))
+ chunkp = &amapp->am_small;
+ else {
+ bucket = UVM_AMAP_BUCKET(&amap, slot);
+ addr = (u_long)(amap.am_buckets + bucket);
+ if (KREAD(kd, addr, &chunkp))
+ return (NULL);
+
+ while (chunkp != NULL) {
+ addr = (u_long)chunkp;
+ if (KREAD(kd, addr, &chunk))
+ return (NULL);
+
+ if (UVM_AMAP_BUCKET(&amap, chunk.ac_baseslot) !=
+ bucket)
+ return (NULL);
+ if (slot >= chunk.ac_baseslot &&
+ slot < chunk.ac_baseslot + chunk.ac_nslot)
+ break;
+
+ chunkp = TAILQ_NEXT(&chunk, ac_list);
+ }
+ if (chunkp == NULL)
+ return (NULL);
+ }
+
+ addr = (u_long)&chunkp->ac_anon[UVM_AMAP_SLOTIDX(slot)];
+ if (KREAD(kd, addr, &anonp))
+ return (NULL);
+
+ return (anonp);
+}
+
static char *
_kvm_ureadm(kvm_t *kd, const struct kinfo_proc *p, u_long va, u_long *cnt)
{
@@ -115,7 +165,6 @@ _kvm_ureadm(kvm_t *kd, const struct kinfo_proc *p, u_long va, u_long *cnt)
struct vmspace vm;
struct vm_anon *anonp, anon;
struct vm_map_entry vme;
- struct vm_amap amap;
struct vm_page pg;
if (kd->swapspc == 0) {
@@ -153,18 +202,11 @@ _kvm_ureadm(kvm_t *kd, const struct kinfo_proc *p, u_long va, u_long *cnt)
if (vme.aref.ar_amap == NULL)
return (NULL);
- addr = (u_long)vme.aref.ar_amap;
- if (KREAD(kd, addr, &amap))
- return (NULL);
-
offset = va - vme.start;
slot = offset / kd->nbpg + vme.aref.ar_pageoff;
- /* sanity-check slot number */
- if (slot > amap.am_nslot)
- return (NULL);
- addr = (u_long)amap.am_anon + (offset / kd->nbpg) * sizeof(anonp);
- if (KREAD(kd, addr, &anonp))
+ anonp = _kvm_findanon(kd, vme.aref.ar_amap, slot);
+ if (anonp == NULL)
return (NULL);
addr = (u_long)anonp;