]> Zhao Yanbai Git Server - minix.git/commitdiff
vm, kernel, top: report memory usage of vm, kernel
authorBen Gras <ben@minix3.org>
Tue, 18 Sep 2012 20:19:22 +0000 (22:19 +0200)
committerBen Gras <ben@minix3.org>
Tue, 18 Sep 2012 21:43:52 +0000 (23:43 +0200)
include/minix/param.h
kernel/arch/i386/pre_init.c
kernel/arch/i386/protect.c
servers/procfs/pid.c
servers/vm/arch/i386/pagetable.c
servers/vm/proto.h
servers/vm/region.c
servers/vm/utility.c
usr.bin/top/top.c

index 9e48218e78b6700f32a9640a18a26de50250f19a..104d7b01641120520396813f98aac8d94f793e34 100644 (file)
@@ -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
index d776ea202040057ea13c6fe9b829b6d12b458554..388972354879ef9a22aea0f6a087ca81f558c439 100644 (file)
@@ -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);
index cd3c6bbec112066dac937e3a2412e87741aab763..23f566107f5a776305037c1904376f81539764f7 100644 (file)
@@ -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;
        }
 }
index faa984aaaac99fee72ad23b23c5dc58db22cb6b6..78ac2cff10446b299284c4d9820a67cb6b7cf19e 100644 (file)
@@ -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");
 }
index 6ec3a363b9c393ddbb470570f1d90a044509db5c..1e5f6e8e4304756261ac9a194c1a343c8d0e7ecf 100644 (file)
@@ -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; }
index 1c2b216381c338a009255111502c8ca1e499b6ae..2824d84e2757ad4ba19c31136f1923b4563fcab9 100644 (file)
@@ -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,
index 9ed75d779820452d8df4fa5104bc6def1d6df84e..de7135a8875d06a54be21a7479873ace8835a398 100644 (file)
@@ -11,6 +11,7 @@
 #include <minix/debug.h>
 #include <minix/bitmap.h>
 #include <minix/hash.h>
+#include <machine/multiboot.h>
 
 #include <sys/mman.h>
 
@@ -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))) {
index 06640d1aa1fee6d3a3afe739d4275d61f99edce7..d4178bb07e5bd7ef0a28672adbcc748baabf0a7b 100644 (file)
@@ -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);
index 296a0f3eadf585a6d08d7d7099ddfd135b2a780c..ceb5d406ff18ebe7ee562bebfc658bc8b27cdd7f 100644 (file)
@@ -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;
                }