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:
parent
201dc52bc5
commit
4050190e78
|
|
@ -24,6 +24,14 @@
|
|||
#include "util.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)
|
||||
{
|
||||
map_free_proc(vmp);
|
||||
|
|
@ -33,6 +41,7 @@ void free_proc(struct vmproc *vmp)
|
|||
vmp->vm_bytecopies = 0;
|
||||
#endif
|
||||
vmp->vm_region_top = 0;
|
||||
reset_vm_rusage(vmp);
|
||||
}
|
||||
|
||||
void clear_proc(struct vmproc *vmp)
|
||||
|
|
@ -43,6 +52,7 @@ void clear_proc(struct vmproc *vmp)
|
|||
vmp->vm_bytecopies = 0;
|
||||
#endif
|
||||
vmp->vm_region_top = 0;
|
||||
reset_vm_rusage(vmp);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
|
|||
|
|
@ -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_unreference(struct phys_region *pr);
|
||||
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_writable(struct phys_region *pr);
|
||||
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,
|
||||
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;
|
||||
u32_t allocflags;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
static int anon_contig_reference(struct phys_region *, struct phys_region *);
|
||||
static int anon_contig_unreference(struct phys_region *pr);
|
||||
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_writable(struct phys_region *pr);
|
||||
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,
|
||||
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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l);
|
||||
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 = {
|
||||
.name = "cache memory",
|
||||
|
|
@ -81,6 +82,7 @@ do_mapcache(message *msg)
|
|||
struct vir_region *vr;
|
||||
struct vmproc *caller;
|
||||
vir_bytes offset;
|
||||
int io = 0;
|
||||
|
||||
if(vm_isokendpt(msg->m_source, &n) != OK) panic("bogus source");
|
||||
caller = &vmproc[n];
|
||||
|
|
@ -113,7 +115,7 @@ do_mapcache(message *msg)
|
|||
assert(vr->length == bytes);
|
||||
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);
|
||||
printf("VM: map_pf failed\n");
|
||||
return ENOMEM;
|
||||
|
|
@ -136,7 +138,7 @@ do_mapcache(message *msg)
|
|||
|
||||
static int cache_pagefault(struct vmproc *vmp, struct vir_region *region,
|
||||
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;
|
||||
assert(ph->ph->phys == MAP_NONE);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
static int phys_unreference(struct phys_region *pr);
|
||||
static int phys_writable(struct phys_region *pr);
|
||||
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);
|
||||
|
||||
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,
|
||||
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;
|
||||
assert(arg != MAP_NONE);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ static void mappedfile_split(struct vmproc *vmp, struct vir_region *vr,
|
|||
struct vir_region *r1, struct vir_region *r2);
|
||||
static int mappedfile_unreference(struct phys_region *pr);
|
||||
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_writable(struct phys_region *pr);
|
||||
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,
|
||||
struct phys_region *ph, int write, vfs_callback_t cb,
|
||||
void *state, int statelen)
|
||||
void *state, int statelen, int *io)
|
||||
{
|
||||
u32_t allocflags;
|
||||
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");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
*io = 1;
|
||||
return SUSPEND;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
|
||||
static int shared_unreference(struct phys_region *pr);
|
||||
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_writable(struct phys_region *pr);
|
||||
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,
|
||||
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 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))) {
|
||||
int r;
|
||||
if((r=map_pf(src_vmp, src_region, ph->offset, write,
|
||||
NULL, NULL, 0)) != OK)
|
||||
NULL, NULL, 0, io)) != OK)
|
||||
return r;
|
||||
if(!(pr = physblock_get(src_region, ph->offset))) {
|
||||
panic("missing region after pagefault handling");
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ typedef struct mem_type {
|
|||
int (*ev_reference)(struct phys_region *pr, struct phys_region *newpr);
|
||||
int (*ev_unreference)(struct phys_region *pr);
|
||||
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);
|
||||
void (*ev_split)(struct vmproc *vmp, struct vir_region *vr,
|
||||
struct vir_region *r1, struct vir_region *r2);
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ static void handle_pagefault(endpoint_t ep, vir_bytes addr, u32_t err, int retry
|
|||
struct vir_region *region;
|
||||
vir_bytes offset;
|
||||
int p, wr = PFERR_WRITE(err);
|
||||
int io = 0;
|
||||
|
||||
if(vm_isokendpt(ep, &p) != OK)
|
||||
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. */
|
||||
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);
|
||||
} else {
|
||||
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.err = err;
|
||||
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) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -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 phys_region **pr);
|
||||
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_handle_memory(struct vmproc *vmp, struct vir_region *region,
|
||||
vir_bytes offset, vir_bytes len, int write, vfs_callback_t cb,
|
||||
|
|
|
|||
|
|
@ -73,14 +73,21 @@ void physblock_set(struct vir_region *region, vir_bytes offset,
|
|||
struct phys_region *newphysr)
|
||||
{
|
||||
int i;
|
||||
struct vmproc *proc;
|
||||
assert(!(offset % VM_PAGE_SIZE));
|
||||
assert(offset >= 0 && offset < region->length);
|
||||
i = offset/VM_PAGE_SIZE;
|
||||
proc = region->parent;
|
||||
assert(proc);
|
||||
if(newphysr) {
|
||||
assert(!region->physblocks[i]);
|
||||
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 {
|
||||
assert(region->physblocks[i]);
|
||||
proc->vm_total -= VM_PAGE_SIZE;
|
||||
}
|
||||
region->physblocks[i] = newphysr;
|
||||
}
|
||||
|
|
@ -671,7 +678,7 @@ u32_t vrallocflags(u32_t flags)
|
|||
/*===========================================================================*
|
||||
* 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 vir_region *region;
|
||||
vir_bytes offset;
|
||||
|
|
@ -679,6 +686,7 @@ int write;
|
|||
vfs_callback_t pf_callback;
|
||||
void *state;
|
||||
int len;
|
||||
int *io;
|
||||
{
|
||||
struct phys_region *ph;
|
||||
int r = OK;
|
||||
|
|
@ -725,7 +733,7 @@ int len;
|
|||
assert(ph->ph);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -774,6 +782,7 @@ int statelen;
|
|||
{
|
||||
vir_bytes offset, lim;
|
||||
int r;
|
||||
int io = 0;
|
||||
|
||||
assert(length > 0);
|
||||
lim = start_offset + length;
|
||||
|
|
@ -781,7 +790,7 @@ int statelen;
|
|||
|
||||
for(offset = start_offset; offset < lim; offset += VM_PAGE_SIZE)
|
||||
if((r = map_pf(vmp, region, offset, write,
|
||||
cb, state, statelen)) != OK)
|
||||
cb, state, statelen, &io)) != OK)
|
||||
return r;
|
||||
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ struct vmproc {
|
|||
#if VMSTATS
|
||||
int vm_bytecopies;
|
||||
#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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user