track dirty vm objects

This commit is contained in:
pooka 2007-08-07 19:37:05 +00:00
parent 34c0850533
commit 7d41c1505d
3 changed files with 41 additions and 19 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: genfs.c,v 1.3 2007/08/07 09:03:43 pooka Exp $ */ /* $NetBSD: genfs.c,v 1.4 2007/08/07 19:37:05 pooka Exp $ */
/* /*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved. * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -167,8 +167,8 @@ genfs_getpages(void *v)
printf("got page %p (off 0x%x)\n", pg, (int)(curoff+bufoff)); printf("got page %p (off 0x%x)\n", pg, (int)(curoff+bufoff));
if (pg == NULL) { if (pg == NULL) {
pg = rumpvm_makepage(&vp->v_uobj, curoff + bufoff, 1); pg = rumpvm_makepage(&vp->v_uobj, curoff + bufoff, 1);
memcpy((void *)pg->uobject, tmpbuf+bufoff, PAGE_SIZE); memcpy((void *)pg->uanon, tmpbuf+bufoff, PAGE_SIZE);
pg->flags = PG_CLEAN; RUMPVM_CLEANPAGE(pg);
} }
ap->a_m[i] = pg; ap->a_m[i] = pg;
} }
@ -205,7 +205,7 @@ genfs_putpages(void *v)
for (pg = TAILQ_FIRST(&uobj->memq); pg; pg = pg_next) { for (pg = TAILQ_FIRST(&uobj->memq); pg; pg = pg_next) {
pg_next = TAILQ_NEXT(pg, listq); pg_next = TAILQ_NEXT(pg, listq);
if (pg->flags & PG_CLEAN) { if (pg->flags & PG_CLEAN) {
rumpvm_freepage(uobj, pg); rumpvm_freepage(pg);
continue; continue;
} }
@ -225,8 +225,8 @@ genfs_putpages(void *v)
if (pg == NULL) if (pg == NULL)
break; break;
memcpy(databuf + (curoff-smallest), memcpy(databuf + (curoff-smallest),
(void *)pg->uobject, PAGE_SIZE); (void *)pg->uanon, PAGE_SIZE);
pg->flags |= PG_CLEAN; RUMPVM_CLEANPAGE(pg);
} }
assert(curoff > smallest); assert(curoff > smallest);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rump.h,v 1.2 2007/08/06 22:20:57 pooka Exp $ */ /* $NetBSD: rump.h,v 1.3 2007/08/07 19:37:05 pooka Exp $ */
/* /*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved. * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -74,6 +74,22 @@ void rump_fakeblk_deregister(const char *);
void rumpvm_init(void); void rumpvm_init(void);
struct vm_page *rumpvm_findpage(struct uvm_object *, voff_t); struct vm_page *rumpvm_findpage(struct uvm_object *, voff_t);
struct vm_page *rumpvm_makepage(struct uvm_object *, voff_t, int); struct vm_page *rumpvm_makepage(struct uvm_object *, voff_t, int);
void rumpvm_freepage(struct uvm_object *, struct vm_page *); void rumpvm_freepage(struct vm_page *);
#define RUMPVM_CLEANPAGE(page) \
do { \
struct uvm_object *uobj_rvm = (page)->uobject; \
if (((page)->flags & PG_CLEAN) == 0) \
uobj_rvm->uo_npages--; \
(page)->flags |= PG_CLEAN; \
} while (/*CONSTCOND*/0)
#define RUMPVM_SOILPAGE(page) \
do { \
struct uvm_object *uobj_rvm = (page)->uobject; \
if (((page)->flags & PG_CLEAN) != 0) \
uobj_rvm->uo_npages++; \
(page)->flags &= ~PG_CLEAN; \
} while (/*CONSTCOND*/0)
#endif /* _SYS_RUMP_H_ */ #endif /* _SYS_RUMP_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm.c,v 1.4 2007/08/07 19:14:51 pooka Exp $ */ /* $NetBSD: vm.c,v 1.5 2007/08/07 19:37:05 pooka Exp $ */
/* /*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved. * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -36,7 +36,7 @@
*/ */
/* /*
* XXX: we abuse pg->uobject for the virtual address of the storage * XXX: we abuse pg->uanon for the virtual address of the storage
* for each page. phys_addr would fit the job description better, * for each page. phys_addr would fit the job description better,
* except that it will create unnecessary lossage on some platforms * except that it will create unnecessary lossage on some platforms
* due to not being a pointer type. * due to not being a pointer type.
@ -98,21 +98,24 @@ rumpvm_makepage(struct uvm_object *uobj, voff_t off, int allocstorage)
memset(pg, 0, sizeof(struct vm_page)); memset(pg, 0, sizeof(struct vm_page));
TAILQ_INSERT_TAIL(&uobj->memq, pg, listq); TAILQ_INSERT_TAIL(&uobj->memq, pg, listq);
pg->offset = off; pg->offset = off;
pg->uobject = uobj;
if (allocstorage) { if (allocstorage) {
pg->uobject = (void *)rumpuser_malloc(PAGE_SIZE, 0); pg->uanon = (void *)rumpuser_malloc(PAGE_SIZE, 0);
memset((void *)pg->uobject, 0, PAGE_SIZE); memset((void *)pg->uanon, 0, PAGE_SIZE);
pg->flags = PG_CLEAN;
} }
return pg; return pg;
} }
void void
rumpvm_freepage(struct uvm_object *uobj, struct vm_page *pg) rumpvm_freepage(struct vm_page *pg)
{ {
struct uvm_object *uobj = pg->uobject;
TAILQ_REMOVE(&uobj->memq, pg, listq); TAILQ_REMOVE(&uobj->memq, pg, listq);
rumpuser_free((void *)pg->uobject); rumpuser_free((void *)pg->uanon);
rumpuser_free(pg); rumpuser_free(pg);
} }
@ -200,7 +203,7 @@ ao_put(struct uvm_object *uobj, voff_t start, voff_t stop, int flags)
return 0; return 0;
while ((pg = TAILQ_FIRST(&uobj->memq)) != NULL) while ((pg = TAILQ_FIRST(&uobj->memq)) != NULL)
rumpvm_freepage(uobj, pg); rumpvm_freepage(pg);
return 0; return 0;
} }
@ -251,9 +254,9 @@ rump_ubc_magic_uiomove(size_t n, struct uio *uio)
pageoff = uio->uio_offset & PAGE_MASK; pageoff = uio->uio_offset & PAGE_MASK;
xfersize = MIN(MIN(n, PAGE_SIZE), PAGE_SIZE-pageoff); xfersize = MIN(MIN(n, PAGE_SIZE), PAGE_SIZE-pageoff);
uiomove((uint8_t *)pgs[i]->uobject + pageoff, xfersize, uio); uiomove((uint8_t *)pgs[i]->uanon + pageoff, xfersize, uio);
if (uio->uio_rw == UIO_WRITE) if (uio->uio_rw == UIO_WRITE)
pgs[i]->flags &= ~PG_CLEAN; RUMPVM_SOILPAGE(pgs[i]);
ubc_offset += xfersize; ubc_offset += xfersize;
n -= xfersize; n -= xfersize;
} }
@ -371,7 +374,7 @@ uvm_vnp_zerorange(struct vnode *vp, off_t off, size_t len)
chunkoff = off & PAGE_MASK; chunkoff = off & PAGE_MASK;
chunklen = MIN(PAGE_SIZE - chunkoff, len); chunklen = MIN(PAGE_SIZE - chunkoff, len);
start = (uint8_t *)pgs[i]->uobject + chunkoff; start = (uint8_t *)pgs[i]->uanon + chunkoff;
memset(start, 0, chunklen); memset(start, 0, chunklen);
pgs[i]->flags &= PG_CLEAN; pgs[i]->flags &= PG_CLEAN;
@ -388,5 +391,8 @@ bool
uvn_clean_p(struct uvm_object *uobj) uvn_clean_p(struct uvm_object *uobj)
{ {
return true; printf("pages %d\n", (int)uobj->uo_npages);
if (uobj->uo_npages < 0)
panic("%s: uo_npages < 0", __func__);
return uobj->uo_npages == 0;
} }