diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -320,6 +320,7 @@ (void)kvm_read(kd, (u_long)proc.p_vmspace, (char *)&vmspace, sizeof(vmspace)); kp->ki_size = vmspace.vm_map.size; + kp->ki_maxsize = vmspace.vm_map.max_size; /* * Approximate the kernel's method of calculating * this field. diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h --- a/sys/compat/freebsd32/freebsd32.h +++ b/sys/compat/freebsd32/freebsd32.h @@ -367,6 +367,7 @@ short ki_spare_short2; gid_t ki_groups[KI_NGROUPS]; uint32_t ki_size; + uint32_t ki_maxsize; int32_t ki_rssize; int32_t ki_swrss; int32_t ki_tsize; @@ -442,7 +443,9 @@ int kvm_map_flags; uint32_t kvm_shp_addr; uint32_t kvm_shp_size; - uint32_t kvm_spare[12]; + uint32_t kvm_map_size; + uint32_t kvm_map_max_size; + uint32_t kvm_spare[10]; }; struct kld_file_stat_1_32 { diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -1154,6 +1154,7 @@ * implement it. Submissions are welcome. */ sbuf_printf(sb, "VmSize:\t%8ju kB\n", B2K((uintmax_t)kp.ki_size)); + sbuf_printf(sb, "VmPeak:\t%8ju kB\n", B2K((uintmax_t)kp.ki_maxsize)); sbuf_printf(sb, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */ sbuf_printf(sb, "VmRSS:\t%8ju kB\n", P2K((uintmax_t)kp.ki_rssize)); sbuf_printf(sb, "VmData:\t%8ju kB\n", P2K((uintmax_t)kp.ki_dsize)); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1162,6 +1162,7 @@ * ASLR and W^X states must be re-evaluated. */ vm_map_lock(map); + map->max_size = 0; vm_map_modflags(map, 0, MAP_WIREFUTURE | MAP_ASLR | MAP_ASLR_IGNSTART | MAP_ASLR_STACK | MAP_WXORX); vm_map_unlock(map); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1139,6 +1139,7 @@ struct vmspace *vm = p->p_vmspace; kp->ki_size = vm->vm_map.size; + kp->ki_maxsize = vm->vm_map.max_size; kp->ki_rssize = vmspace_resident_count(vm); /*XXX*/ FOREACH_THREAD_IN_PROC(p, td0) kp->ki_rssize += td0->td_kstack_pages; @@ -1445,6 +1446,7 @@ for (i = 0; i < KI_NGROUPS; i++) CP(*ki, *ki32, ki_groups[i]); CP(*ki, *ki32, ki_size); + CP(*ki, *ki32, ki_maxsize); CP(*ki, *ki32, ki_rssize); CP(*ki, *ki32, ki_swrss); CP(*ki, *ki32, ki_tsize); @@ -3264,6 +3266,8 @@ kvm.kvm_stack_size = vmspace->vm_ssize; kvm.kvm_shp_addr = vmspace->vm_shp_base; kvm.kvm_shp_size = p->p_sysent->sv_shared_page_len; + kvm.kvm_map_size = vmspace->vm_map.size; + kvm.kvm_map_max_size = vmspace->vm_map.max_size; if ((vmspace->vm_map.flags & MAP_WIREFUTURE) != 0) kvm.kvm_map_flags |= KMAP_FLAG_WIREFUTURE; if ((vmspace->vm_map.flags & MAP_ASLR) != 0) @@ -3293,6 +3297,8 @@ kvm32.kvm_stack_size = (uint32_t)kvm.kvm_stack_size; kvm32.kvm_shp_addr = (uint32_t)kvm.kvm_shp_addr; kvm32.kvm_shp_size = (uint32_t)kvm.kvm_shp_size; + kvm32.kvm_map_size = (uint32_t)kvm.kvm_map_size; + kvm32.kvm_map_max_size = (uint32_t)kvm.kvm_map_max_size; kvm32.kvm_map_flags = kvm.kvm_map_flags; error = SYSCTL_OUT(req, &kvm32, sizeof(kvm32)); goto out; diff --git a/sys/sys/user.h b/sys/sys/user.h --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -84,7 +84,7 @@ * function kvm_proclist in lib/libkvm/kvm_proc.c . */ #define KI_NSPARE_INT 2 -#define KI_NSPARE_LONG 12 +#define KI_NSPARE_LONG 11 #define KI_NSPARE_PTR 5 #ifndef _KERNEL @@ -213,6 +213,7 @@ struct pwddesc *ki_pd; /* pointer to process paths info */ void *ki_spareptrs[KI_NSPARE_PTR]; /* spare room for growth */ long ki_sparelongs[KI_NSPARE_LONG]; /* spare room for growth */ + vm_size_t ki_maxsize; /* maximum virtual size so far */ long ki_sflag; /* PS_* flags */ long ki_tdflags; /* XXXKSE kthread flag */ }; @@ -652,7 +653,9 @@ int kvm_map_flags; uintptr_t kvm_shp_addr; size_t kvm_shp_size; - uintptr_t kvm_spare[12]; + size_t kvm_map_size; + size_t kvm_map_max_size; + uintptr_t kvm_spare[10]; }; #ifdef _KERNEL diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -207,6 +207,7 @@ struct mtx system_mtx; int nentries; /* Number of entries */ vm_size_t size; /* virtual size */ + vm_size_t max_size; /* Max of virtual size so far */ u_int timestamp; /* Version number */ u_char needs_wakeup; u_char system_map; /* (c) Am I a system map? */ diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -889,6 +889,7 @@ { map->header.eflags = MAP_ENTRY_HEADER; + map->max_size = 0; map->needs_wakeup = FALSE; map->system_map = 0; map->pmap = pmap; @@ -1756,8 +1757,11 @@ KASSERT((prev_entry->eflags & MAP_ENTRY_USER_WIRED) == 0, ("prev_entry %p has incoherent wiring", prev_entry)); - if ((prev_entry->eflags & MAP_ENTRY_GUARD) == 0) + if ((prev_entry->eflags & MAP_ENTRY_GUARD) == 0) { map->size += end - prev_entry->end; + if (map->size > map->max_size) + map->max_size = map->size; + } vm_map_entry_resize(map, prev_entry, end - prev_entry->end); *res = vm_map_try_merge_entries(map, prev_entry, @@ -1812,8 +1816,11 @@ * Insert the new entry into the list */ vm_map_entry_link(map, new_entry); - if ((new_entry->eflags & MAP_ENTRY_GUARD) == 0) + if ((new_entry->eflags & MAP_ENTRY_GUARD) == 0) { map->size += new_entry->end - new_entry->start; + if (map->size > map->max_size) + map->max_size = map->size; + } /* * Try to coalesce the new entry with both the previous and next @@ -4327,6 +4334,8 @@ return; entrysize = entry->end - entry->start; vm2->vm_map.size += entrysize; + if (vm2->vm_map.size > vm2->vm_map.max_size) + vm2->vm_map.max_size = vm2->vm_map.size; if (entry->eflags & (MAP_ENTRY_GROWS_DOWN | MAP_ENTRY_GROWS_UP)) { vm2->vm_ssize += btoc(entrysize); } else if (entry->start >= (vm_offset_t)vm1->vm_daddr && @@ -4915,6 +4924,8 @@ stack_entry->end += grow_amount; } map->size += grow_amount; + if (map->size > map->max_size) + map->max_size = map->size; rv = KERN_SUCCESS; } else rv = KERN_FAILURE;