Add vm_total, vm_total_max, vm_minor_page_fault and vm_major_page_fault

Add vm_total, vm_total_max, vm_minor_page_fault and vm_major_page_fault to vm
server to implement getrusage
This commit is contained in:
Xiaoguang Sun 2013-06-09 15:15:39 +00:00 committed by Kees Jongenburger
parent 85c3fce1a7
commit 35eb823963
12 changed files with 62 additions and 22 deletions

View File

@ -24,6 +24,14 @@
#include "util.h" #include "util.h"
#include "sanitycheck.h" #include "sanitycheck.h"
static void reset_vm_rusage(struct vmproc *vmp)
{
vmp->vm_total = 0;
vmp->vm_total_max = 0;
vmp->vm_minor_page_fault = 0;
vmp->vm_major_page_fault = 0;
}
void free_proc(struct vmproc *vmp) void free_proc(struct vmproc *vmp)
{ {
map_free_proc(vmp); map_free_proc(vmp);
@ -33,6 +41,7 @@ void free_proc(struct vmproc *vmp)
vmp->vm_bytecopies = 0; vmp->vm_bytecopies = 0;
#endif #endif
vmp->vm_region_top = 0; vmp->vm_region_top = 0;
reset_vm_rusage(vmp);
} }
void clear_proc(struct vmproc *vmp) void clear_proc(struct vmproc *vmp)
@ -43,6 +52,7 @@ void clear_proc(struct vmproc *vmp)
vmp->vm_bytecopies = 0; vmp->vm_bytecopies = 0;
#endif #endif
vmp->vm_region_top = 0; vmp->vm_region_top = 0;
reset_vm_rusage(vmp);
} }
/*===========================================================================* /*===========================================================================*

View File

@ -22,7 +22,8 @@ static void anon_split(struct vmproc *vmp, struct vir_region *vr,
static int anon_lowshrink(struct vir_region *vr, vir_bytes len); static int anon_lowshrink(struct vir_region *vr, vir_bytes len);
static int anon_unreference(struct phys_region *pr); static int anon_unreference(struct phys_region *pr);
static int anon_pagefault(struct vmproc *vmp, struct vir_region *region, static int anon_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *, int); struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io);
static int anon_sanitycheck(struct phys_region *pr, char *file, int line); static int anon_sanitycheck(struct phys_region *pr, char *file, int line);
static int anon_writable(struct phys_region *pr); static int anon_writable(struct phys_region *pr);
static int anon_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l); static int anon_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l);
@ -51,7 +52,8 @@ static int anon_unreference(struct phys_region *pr)
} }
static int anon_pagefault(struct vmproc *vmp, struct vir_region *region, static int anon_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *st, int l) struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io)
{ {
phys_bytes new_page, new_page_cl; phys_bytes new_page, new_page_cl;
u32_t allocflags; u32_t allocflags;

View File

@ -11,7 +11,8 @@
static int anon_contig_reference(struct phys_region *, struct phys_region *); static int anon_contig_reference(struct phys_region *, struct phys_region *);
static int anon_contig_unreference(struct phys_region *pr); static int anon_contig_unreference(struct phys_region *pr);
static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region, static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *st, int); struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io);
static int anon_contig_sanitycheck(struct phys_region *pr, char *file, int line); static int anon_contig_sanitycheck(struct phys_region *pr, char *file, int line);
static int anon_contig_writable(struct phys_region *pr); static int anon_contig_writable(struct phys_region *pr);
static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l); static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l);
@ -29,7 +30,8 @@ struct mem_type mem_type_anon_contig = {
}; };
static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region, static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *s, int l) struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io)
{ {
panic("anon_contig_pagefault: pagefault cannot happen"); panic("anon_contig_pagefault: pagefault cannot happen");
} }

View File

@ -29,7 +29,8 @@ static int cache_sanitycheck(struct phys_region *pr, char *file, int line);
static int cache_writable(struct phys_region *pr); static int cache_writable(struct phys_region *pr);
static int cache_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l); static int cache_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l);
static int cache_pagefault(struct vmproc *vmp, struct vir_region *region, static int cache_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *, int); struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io);
struct mem_type mem_type_cache = { struct mem_type mem_type_cache = {
.name = "cache memory", .name = "cache memory",
@ -81,6 +82,7 @@ do_mapcache(message *msg)
struct vir_region *vr; struct vir_region *vr;
struct vmproc *caller; struct vmproc *caller;
vir_bytes offset; vir_bytes offset;
int io = 0;
if(vm_isokendpt(msg->m_source, &n) != OK) panic("bogus source"); if(vm_isokendpt(msg->m_source, &n) != OK) panic("bogus source");
caller = &vmproc[n]; caller = &vmproc[n];
@ -113,7 +115,7 @@ do_mapcache(message *msg)
assert(vr->length == bytes); assert(vr->length == bytes);
assert(offset < vr->length); assert(offset < vr->length);
if(map_pf(caller, vr, offset, 1, NULL, NULL, 0) != OK) { if(map_pf(caller, vr, offset, 1, NULL, NULL, 0, &io) != OK) {
map_unmap_region(caller, vr, 0, bytes); map_unmap_region(caller, vr, 0, bytes);
printf("VM: map_pf failed\n"); printf("VM: map_pf failed\n");
return ENOMEM; return ENOMEM;
@ -136,7 +138,7 @@ do_mapcache(message *msg)
static int cache_pagefault(struct vmproc *vmp, struct vir_region *region, static int cache_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, struct phys_region *ph, int write, vfs_callback_t cb,
void *state, int len) void *state, int len, int *io)
{ {
vir_bytes offset = ph->offset; vir_bytes offset = ph->offset;
assert(ph->ph->phys == MAP_NONE); assert(ph->ph->phys == MAP_NONE);

View File

@ -17,7 +17,8 @@
static int phys_unreference(struct phys_region *pr); static int phys_unreference(struct phys_region *pr);
static int phys_writable(struct phys_region *pr); static int phys_writable(struct phys_region *pr);
static int phys_pagefault(struct vmproc *vmp, struct vir_region *region, static int phys_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *, int); struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io);
static int phys_copy(struct vir_region *vr, struct vir_region *newvr); static int phys_copy(struct vir_region *vr, struct vir_region *newvr);
struct mem_type mem_type_directphys = { struct mem_type mem_type_directphys = {
@ -34,7 +35,8 @@ static int phys_unreference(struct phys_region *pr)
} }
static int phys_pagefault(struct vmproc *vmp, struct vir_region *region, static int phys_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *st, int len) struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io)
{ {
phys_bytes arg = region->param.phys, phmem; phys_bytes arg = region->param.phys, phmem;
assert(arg != MAP_NONE); assert(arg != MAP_NONE);

View File

@ -18,7 +18,8 @@ static void mappedfile_split(struct vmproc *vmp, struct vir_region *vr,
struct vir_region *r1, struct vir_region *r2); struct vir_region *r1, struct vir_region *r2);
static int mappedfile_unreference(struct phys_region *pr); static int mappedfile_unreference(struct phys_region *pr);
static int mappedfile_pagefault(struct vmproc *vmp, struct vir_region *region, static int mappedfile_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t callback, void *, int); struct phys_region *ph, int write, vfs_callback_t callback, void *state,
int len, int *io);
static int mappedfile_sanitycheck(struct phys_region *pr, char *file, int line); static int mappedfile_sanitycheck(struct phys_region *pr, char *file, int line);
static int mappedfile_writable(struct phys_region *pr); static int mappedfile_writable(struct phys_region *pr);
static int mappedfile_copy(struct vir_region *vr, struct vir_region *newvr); static int mappedfile_copy(struct vir_region *vr, struct vir_region *newvr);
@ -72,7 +73,7 @@ static int cow_block(struct vmproc *vmp, struct vir_region *region,
static int mappedfile_pagefault(struct vmproc *vmp, struct vir_region *region, static int mappedfile_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, struct phys_region *ph, int write, vfs_callback_t cb,
void *state, int statelen) void *state, int statelen, int *io)
{ {
u32_t allocflags; u32_t allocflags;
int procfd = region->param.file.fdref->fd; int procfd = region->param.file.fdref->fd;
@ -123,7 +124,7 @@ static int mappedfile_pagefault(struct vmproc *vmp, struct vir_region *region,
printf("VM: mappedfile_pagefault: vfs_request failed\n"); printf("VM: mappedfile_pagefault: vfs_request failed\n");
return ENOMEM; return ENOMEM;
} }
*io = 1;
return SUSPEND; return SUSPEND;
} }

View File

@ -15,7 +15,8 @@
static int shared_unreference(struct phys_region *pr); static int shared_unreference(struct phys_region *pr);
static int shared_pagefault(struct vmproc *vmp, struct vir_region *region, static int shared_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *, int); struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io);
static int shared_sanitycheck(struct phys_region *pr, char *file, int line); static int shared_sanitycheck(struct phys_region *pr, char *file, int line);
static int shared_writable(struct phys_region *pr); static int shared_writable(struct phys_region *pr);
static void shared_delete(struct vir_region *region); static void shared_delete(struct vir_region *region);
@ -110,7 +111,7 @@ static void shared_delete(struct vir_region *region)
static int shared_pagefault(struct vmproc *vmp, struct vir_region *region, static int shared_pagefault(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, struct phys_region *ph, int write, vfs_callback_t cb,
void *state, int statelen) void *state, int statelen, int *io)
{ {
struct vir_region *src_region; struct vir_region *src_region;
struct vmproc *src_vmp; struct vmproc *src_vmp;
@ -126,7 +127,7 @@ static int shared_pagefault(struct vmproc *vmp, struct vir_region *region,
if(!(pr = physblock_get(src_region, ph->offset))) { if(!(pr = physblock_get(src_region, ph->offset))) {
int r; int r;
if((r=map_pf(src_vmp, src_region, ph->offset, write, if((r=map_pf(src_vmp, src_region, ph->offset, write,
NULL, NULL, 0)) != OK) NULL, NULL, 0, io)) != OK)
return r; return r;
if(!(pr = physblock_get(src_region, ph->offset))) { if(!(pr = physblock_get(src_region, ph->offset))) {
panic("missing region after pagefault handling"); panic("missing region after pagefault handling");

View File

@ -16,7 +16,8 @@ typedef struct mem_type {
int (*ev_reference)(struct phys_region *pr, struct phys_region *newpr); int (*ev_reference)(struct phys_region *pr, struct phys_region *newpr);
int (*ev_unreference)(struct phys_region *pr); int (*ev_unreference)(struct phys_region *pr);
int (*ev_pagefault)(struct vmproc *vmp, struct vir_region *region, int (*ev_pagefault)(struct vmproc *vmp, struct vir_region *region,
struct phys_region *ph, int write, vfs_callback_t cb, void *, int); struct phys_region *ph, int write, vfs_callback_t cb, void *state,
int len, int *io);
int (*ev_resize)(struct vmproc *vmp, struct vir_region *vr, vir_bytes len); int (*ev_resize)(struct vmproc *vmp, struct vir_region *vr, vir_bytes len);
void (*ev_split)(struct vmproc *vmp, struct vir_region *vr, void (*ev_split)(struct vmproc *vmp, struct vir_region *vr,
struct vir_region *r1, struct vir_region *r2); struct vir_region *r1, struct vir_region *r2);

View File

@ -70,6 +70,7 @@ static void handle_pagefault(endpoint_t ep, vir_bytes addr, u32_t err, int retry
struct vir_region *region; struct vir_region *region;
vir_bytes offset; vir_bytes offset;
int p, wr = PFERR_WRITE(err); int p, wr = PFERR_WRITE(err);
int io = 0;
if(vm_isokendpt(ep, &p) != OK) if(vm_isokendpt(ep, &p) != OK)
panic("handle_pagefault: endpoint wrong: %d", ep); panic("handle_pagefault: endpoint wrong: %d", ep);
@ -111,7 +112,7 @@ static void handle_pagefault(endpoint_t ep, vir_bytes addr, u32_t err, int retry
/* Access is allowed; handle it. */ /* Access is allowed; handle it. */
if(retry) { if(retry) {
result = map_pf(vmp, region, offset, wr, NULL, NULL, 0); result = map_pf(vmp, region, offset, wr, NULL, NULL, 0, &io);
assert(result != SUSPEND); assert(result != SUSPEND);
} else { } else {
struct pf_state state; struct pf_state state;
@ -119,8 +120,12 @@ static void handle_pagefault(endpoint_t ep, vir_bytes addr, u32_t err, int retry
state.vaddr = addr; state.vaddr = addr;
state.err = err; state.err = err;
result = map_pf(vmp, region, offset, wr, pf_cont, result = map_pf(vmp, region, offset, wr, pf_cont,
&state, sizeof(state)); &state, sizeof(state), &io);
} }
if (io)
vmp->vm_major_page_fault++;
else
vmp->vm_minor_page_fault++;
if(result == SUSPEND) { if(result == SUSPEND) {
return; return;

View File

@ -143,7 +143,8 @@ int map_proc_copy_from(struct vmproc *dst, struct vmproc *src, struct
struct vir_region *map_lookup(struct vmproc *vmp, vir_bytes addr, struct vir_region *map_lookup(struct vmproc *vmp, vir_bytes addr,
struct phys_region **pr); struct phys_region **pr);
int map_pf(struct vmproc *vmp, struct vir_region *region, vir_bytes int map_pf(struct vmproc *vmp, struct vir_region *region, vir_bytes
offset, int write, vfs_callback_t pf_callback, void *state, int); offset, int write, vfs_callback_t pf_callback, void *state, int len,
int *io);
int map_pin_memory(struct vmproc *vmp); int map_pin_memory(struct vmproc *vmp);
int map_handle_memory(struct vmproc *vmp, struct vir_region *region, int map_handle_memory(struct vmproc *vmp, struct vir_region *region,
vir_bytes offset, vir_bytes len, int write, vfs_callback_t cb, vir_bytes offset, vir_bytes len, int write, vfs_callback_t cb,

View File

@ -73,14 +73,21 @@ void physblock_set(struct vir_region *region, vir_bytes offset,
struct phys_region *newphysr) struct phys_region *newphysr)
{ {
int i; int i;
struct vmproc *proc;
assert(!(offset % VM_PAGE_SIZE)); assert(!(offset % VM_PAGE_SIZE));
assert(offset >= 0 && offset < region->length); assert(offset >= 0 && offset < region->length);
i = offset/VM_PAGE_SIZE; i = offset/VM_PAGE_SIZE;
proc = region->parent;
assert(proc);
if(newphysr) { if(newphysr) {
assert(!region->physblocks[i]); assert(!region->physblocks[i]);
assert(newphysr->offset == offset); assert(newphysr->offset == offset);
proc->vm_total += VM_PAGE_SIZE;
if (proc->vm_total > proc->vm_total_max)
proc->vm_total_max = proc->vm_total;
} else { } else {
assert(region->physblocks[i]); assert(region->physblocks[i]);
proc->vm_total -= VM_PAGE_SIZE;
} }
region->physblocks[i] = newphysr; region->physblocks[i] = newphysr;
} }
@ -671,7 +678,7 @@ u32_t vrallocflags(u32_t flags)
/*===========================================================================* /*===========================================================================*
* map_pf * * map_pf *
*===========================================================================*/ *===========================================================================*/
int map_pf(vmp, region, offset, write, pf_callback, state, len) int map_pf(vmp, region, offset, write, pf_callback, state, len, io)
struct vmproc *vmp; struct vmproc *vmp;
struct vir_region *region; struct vir_region *region;
vir_bytes offset; vir_bytes offset;
@ -679,6 +686,7 @@ int write;
vfs_callback_t pf_callback; vfs_callback_t pf_callback;
void *state; void *state;
int len; int len;
int *io;
{ {
struct phys_region *ph; struct phys_region *ph;
int r = OK; int r = OK;
@ -725,7 +733,7 @@ int len;
assert(ph->ph); assert(ph->ph);
if((r = ph->memtype->ev_pagefault(vmp, if((r = ph->memtype->ev_pagefault(vmp,
region, ph, write, pf_callback, state, len)) == SUSPEND) { region, ph, write, pf_callback, state, len, io)) == SUSPEND) {
return SUSPEND; return SUSPEND;
} }
@ -774,6 +782,7 @@ int statelen;
{ {
vir_bytes offset, lim; vir_bytes offset, lim;
int r; int r;
int io = 0;
assert(length > 0); assert(length > 0);
lim = start_offset + length; lim = start_offset + length;
@ -781,7 +790,7 @@ int statelen;
for(offset = start_offset; offset < lim; offset += VM_PAGE_SIZE) for(offset = start_offset; offset < lim; offset += VM_PAGE_SIZE)
if((r = map_pf(vmp, region, offset, write, if((r = map_pf(vmp, region, offset, write,
cb, state, statelen)) != OK) cb, state, statelen, &io)) != OK)
return r; return r;
return OK; return OK;

View File

@ -25,6 +25,10 @@ struct vmproc {
#if VMSTATS #if VMSTATS
int vm_bytecopies; int vm_bytecopies;
#endif #endif
vir_bytes vm_total;
vir_bytes vm_total_max;
u64_t vm_minor_page_fault;
u64_t vm_major_page_fault;
}; };
/* Bits for vm_flags */ /* Bits for vm_flags */