From fe6e291f59ff05359f3a67d10dec8ce82117d6ff Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Tue, 18 Sep 2012 22:19:22 +0200 Subject: [PATCH] vm, kernel, top: report memory usage of vm, kernel --- include/minix/param.h | 2 ++ kernel/arch/i386/pre_init.c | 5 +++++ kernel/arch/i386/protect.c | 6 ++++++ servers/procfs/pid.c | 17 ++++++++++------- servers/vm/arch/i386/pagetable.c | 14 +++++++++++--- servers/vm/proto.h | 2 ++ servers/vm/region.c | 24 ++++++++++++++++++++++++ servers/vm/utility.c | 7 ++++--- usr.bin/top/top.c | 7 +++++-- 9 files changed, 69 insertions(+), 15 deletions(-) diff --git a/include/minix/param.h b/include/minix/param.h index 9e48218e7..104d7b016 100644 --- a/include/minix/param.h +++ b/include/minix/param.h @@ -40,6 +40,8 @@ typedef struct kinfo { int nr_tasks; /* number of kernel tasks */ char release[6]; /* kernel release number */ char version[6]; /* kernel version number */ + int vm_allocated_bytes; /* allocated by kernel to load vm */ + int kernel_allocated_bytes; /* used by kernel */ } kinfo_t; #endif diff --git a/kernel/arch/i386/pre_init.c b/kernel/arch/i386/pre_init.c index d776ea202..388972354 100644 --- a/kernel/arch/i386/pre_init.c +++ b/kernel/arch/i386/pre_init.c @@ -160,6 +160,11 @@ void get_parameters(u32_t ebx, kinfo_t *cbi) cbi->user_sp &= 0xF0000000; cbi->user_end = cbi->user_sp; + /* kernel bytes without bootstrap code/data that is currently + * still needed but will be freed after bootstrapping. + */ + kinfo.kernel_allocated_bytes = (phys_bytes) &_kern_size; + assert(!(cbi->bootstrap_start % I386_PAGE_SIZE)); cbi->bootstrap_len = rounddown(cbi->bootstrap_len, I386_PAGE_SIZE); assert(mbi->flags & MULTIBOOT_INFO_MODS); diff --git a/kernel/arch/i386/protect.c b/kernel/arch/i386/protect.c index cd3c6bbec..23f566107 100644 --- a/kernel/arch/i386/protect.c +++ b/kernel/arch/i386/protect.c @@ -323,6 +323,8 @@ void prot_init() prot_init_done = 1; } +static int alloc_for_vm = 0; + void arch_post_init(void) { /* Let memory mapping code know what's going on at bootstrap time */ @@ -337,6 +339,7 @@ int libexec_pg_alloc(struct exec_info *execi, off_t vaddr, size_t len) pg_map(PG_ALLOCATEME, vaddr, vaddr+len, &kinfo); pg_load(); memset((char *) vaddr, 0, len); + alloc_for_vm += len; return OK; } @@ -383,5 +386,8 @@ void arch_boot_proc(struct boot_image *ip, struct proc *rp) /* Free VM blob that was just copied into existence. */ cut_memmap(&kinfo, mod->mod_start, mod->mod_end); + + /* Remember them */ + kinfo.vm_allocated_bytes = alloc_for_vm; } } diff --git a/servers/procfs/pid.c b/servers/procfs/pid.c index faa984aaa..78ac2cff1 100644 --- a/servers/procfs/pid.c +++ b/servers/procfs/pid.c @@ -107,15 +107,15 @@ static void pid_psinfo(int i) ex64lo(proc[i].p_cycles) ); - /* If the process is not a kernel task, we add some extra info. */ - if (!task) { - memset(&vui, 0, sizeof(vui)); + memset(&vui, 0, sizeof(vui)); - if (!is_zombie(i)) { - /* We don't care if this fails. */ - (void) vm_info_usage(proc[i].p_endpoint, &vui); - } + if (!is_zombie(i)) { + /* We don't care if this fails. */ + (void) vm_info_usage(proc[i].p_endpoint, &vui); + } + /* If the process is not a kernel task, we add some extra info. */ + if (!task) { if (mproc[pi].mp_flags & PAUSED) p_state = PSTATE_PAUSED; else if (mproc[pi].mp_flags & WAITING) @@ -165,6 +165,9 @@ static void pid_psinfo(int i) ex64hi(proc[i].p_kcall_cycles), ex64lo(proc[i].p_kcall_cycles)); + /* add total memory for tasks at the end */ + if(task) buf_printf(" %lu", vui.vui_total); + /* Newline at the end of the file. */ buf_printf("\n"); } diff --git a/servers/vm/arch/i386/pagetable.c b/servers/vm/arch/i386/pagetable.c index 6ec3a363b..1e5f6e8e4 100644 --- a/servers/vm/arch/i386/pagetable.c +++ b/servers/vm/arch/i386/pagetable.c @@ -36,6 +36,8 @@ #include "memory.h" +static int vm_self_pages; + /* PDE used to map in kernel, kernel physical address. */ static int pagedir_pde = -1; static u32_t global_bit = 0, pagedir_pde_val; @@ -67,6 +69,9 @@ static struct { phys_bytes phys; } sparepages[SPAREPAGES]; +extern char _end; +#define is_staticaddr(v) ((vir_bytes) (v) < (vir_bytes) &_end) + #define MAX_KERNMAPPINGS 10 static struct { phys_bytes phys_addr; /* Physical addr. */ @@ -130,7 +135,6 @@ static u32_t findhole(void) int pde = 0, try_restart; static u32_t lastv = 0; pt_t *pt = &vmprocess->vm_pt; - extern char _end; vir_bytes vmin, vmax; vmin = (vir_bytes) (&_end) & I386_VM_ADDR_MASK; /* marks end of VM BSS */ @@ -188,9 +192,8 @@ static u32_t findhole(void) void vm_freepages(vir_bytes vir, int pages) { assert(!(vir % I386_PAGE_SIZE)); - extern char _end; - if(vir < (vir_bytes) &_end) { + if(is_staticaddr(vir)) { printf("VM: not freeing static page\n"); return; } @@ -200,6 +203,8 @@ void vm_freepages(vir_bytes vir, int pages) WMF_OVERWRITE | WMF_FREE) != OK) panic("vm_freepages: pt_writemap failed"); + vm_self_pages--; + #if SANITYCHECKS /* If SANITYCHECKS are on, flush tlb so accessing freed pages is * always trapped, also if not in tlb. @@ -288,6 +293,7 @@ void *vm_allocpage(phys_bytes *phys, int reason) util_stacktrace(); printf("VM: warning: out of spare pages\n"); } + if(!is_staticaddr(s)) vm_self_pages++; return s; } @@ -330,6 +336,7 @@ void *vm_allocpage(phys_bytes *phys, int reason) /* Return user-space-ready pointer to it. */ ret = (void *) loc; + vm_self_pages++; return ret; } @@ -1135,3 +1142,4 @@ void pt_cycle(void) vm_checkspares(); } +int get_vm_self_pages(void) { return vm_self_pages; } diff --git a/servers/vm/proto.h b/servers/vm/proto.h index 1c2b21638..2824d84e2 100644 --- a/servers/vm/proto.h +++ b/servers/vm/proto.h @@ -100,6 +100,7 @@ void pt_cycle(void); int pt_mapkernel(pt_t *pt); void vm_pagelock(void *vir, int lockflag); int vm_addrok(void *vir, int write); +int get_vm_self_pages(void); #if SANITYCHECKS void pt_sanitycheck(pt_t *pt, char *file, int line); @@ -159,6 +160,7 @@ int map_get_ref(struct vmproc *vmp, vir_bytes addr, u8_t *cnt); void get_stats_info(struct vm_stats_info *vsi); void get_usage_info(struct vmproc *vmp, struct vm_usage_info *vui); +void get_usage_info_kernel(struct vm_usage_info *vui); int get_region_info(struct vmproc *vmp, struct vm_region_info *vri, int count, vir_bytes *nextp); int copy_abs2region(phys_bytes abs, struct vir_region *destregion, diff --git a/servers/vm/region.c b/servers/vm/region.c index 9ed75d779..de7135a88 100644 --- a/servers/vm/region.c +++ b/servers/vm/region.c @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -1879,6 +1880,19 @@ void get_stats_info(struct vm_stats_info *vsi) vsi->vsi_cached++; } +void get_usage_info_kernel(struct vm_usage_info *vui) +{ + memset(vui, 0, sizeof(*vui)); + vui->vui_total = kernel_boot_info.kernel_allocated_bytes; +} + +static void get_usage_info_vm(struct vm_usage_info *vui) +{ + memset(vui, 0, sizeof(*vui)); + vui->vui_total = kernel_boot_info.vm_allocated_bytes + + get_vm_self_pages() * VM_PAGE_SIZE; +} + /*========================================================================* * get_usage_info * *========================================================================*/ @@ -1892,6 +1906,16 @@ void get_usage_info(struct vmproc *vmp, struct vm_usage_info *vui) memset(vui, 0, sizeof(*vui)); + if(vmp->vm_endpoint == VM_PROC_NR) { + get_usage_info_vm(vui); + return; + } + + if(vmp->vm_endpoint < 0) { + get_usage_info_kernel(vui); + return; + } + while((vr = region_get_iter(&v_iter))) { physr_start_iter_least(vr->phys, &iter); while((ph = physr_get_iter(&iter))) { diff --git a/servers/vm/utility.c b/servers/vm/utility.c index 06640d1aa..d4178bb07 100644 --- a/servers/vm/utility.c +++ b/servers/vm/utility.c @@ -122,10 +122,11 @@ int do_info(message *m) break; case VMIW_USAGE: - if (vm_isokendpt(m->VMI_EP, &pr) != OK) + if(m->VMI_EP < 0) + get_usage_info_kernel(&vui); + else if (vm_isokendpt(m->VMI_EP, &pr) != OK) return EINVAL; - - get_usage_info(&vmproc[pr], &vui); + else get_usage_info(&vmproc[pr], &vui); addr = (vir_bytes) &vui; size = sizeof(vui); diff --git a/usr.bin/top/top.c b/usr.bin/top/top.c index 296a0f3ea..ceb5d406f 100644 --- a/usr.bin/top/top.c +++ b/usr.bin/top/top.c @@ -173,6 +173,10 @@ void parse_file(pid_t pid) } } + if ((p->p_flags & IS_TASK)) { + fscanf(fp, " %lu ", &p->p_memory); + } + p->p_flags |= USED; fclose(fp); @@ -458,7 +462,6 @@ void print_procs(int maxlines, } if(p-NR_TASKS == KERNEL) { kernelticks = uticks; - continue; } if(!(proc2[p].p_flags & IS_TASK)) { if(proc2[p].p_flags & IS_SYSTEM) @@ -508,7 +511,7 @@ void print_procs(int maxlines, pr = tick_procs[p].p; - if(pr->p_flags & IS_TASK) { + if((pr->p_flags & IS_TASK) && pr->p_pid != KERNEL) { /* skip old kernel tasks as they don't run anymore */ continue; } -- 2.44.0