提交 4cca7d25 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

copy-on-write and copy-on-demand

passes forktest on 1+2 cpu, but ...
上级 372d4c19
...@@ -21,9 +21,7 @@ exec(char *path, char **argv) ...@@ -21,9 +21,7 @@ exec(char *path, char **argv)
pde_t *pgdir = 0, *oldpgdir; pde_t *pgdir = 0, *oldpgdir;
struct vmap *vmap = 0, *oldvmap; struct vmap *vmap = 0, *oldvmap;
struct vmnode *vmn = 0; struct vmnode *vmn = 0;
int odp = 0; int odp = 1;
cprintf("exec: %s\n", path);
if((ip = namei(path)) == 0) if((ip = namei(path)) == 0)
return -1; return -1;
......
...@@ -205,6 +205,8 @@ fork(int flags) ...@@ -205,6 +205,8 @@ fork(int flags)
struct proc *np; struct proc *np;
uint cow = 1; uint cow = 1;
// cprintf("%d: fork\n", proc->pid);
// Allocate process. // Allocate process.
if((np = allocproc()) == 0) if((np = allocproc()) == 0)
return -1; return -1;
...@@ -249,6 +251,7 @@ fork(int flags) ...@@ -249,6 +251,7 @@ fork(int flags)
acquire(&proc->lock); acquire(&proc->lock);
SLIST_INSERT_HEAD(&proc->childq, np, child_next); SLIST_INSERT_HEAD(&proc->childq, np, child_next);
release(&proc->lock); release(&proc->lock);
// cprintf("%d: fork done (pid %d)\n", proc->pid, pid);
return pid; return pid;
} }
......
...@@ -246,6 +246,8 @@ vmn_alloc(uint npg, uint type) ...@@ -246,6 +246,8 @@ vmn_alloc(uint npg, uint type)
if(npg > sizeof(n->page) / sizeof(n->page[0])) { if(npg > sizeof(n->page) / sizeof(n->page[0])) {
panic("vmnode too big\n"); panic("vmnode too big\n");
} }
for (uint i = 0; i < sizeof(n->page) / sizeof(n->page[0]); i++)
n->page[i] = 0;
n->npages = npg; n->npages = npg;
n->ref = 0; n->ref = 0;
n->ip = 0; n->ip = 0;
...@@ -288,7 +290,8 @@ vmn_free(struct vmnode *n) ...@@ -288,7 +290,8 @@ vmn_free(struct vmnode *n)
} }
} }
if (n->ip) if (n->ip)
panic("vmn_free: drop inode ref"); iput(n->ip);
n->ip = 0;
n->alloc = 0; n->alloc = 0;
} }
...@@ -302,10 +305,21 @@ vmn_decref(struct vmnode *n) ...@@ -302,10 +305,21 @@ vmn_decref(struct vmnode *n)
struct vmnode * struct vmnode *
vmn_copy(struct vmnode *n) vmn_copy(struct vmnode *n)
{ {
struct vmnode *c = vmn_allocpg(n->npages); struct vmnode *c = vmn_alloc(n->npages, n->type);
if(c != 0) { if(c != 0) {
for(uint i = 0; i < n->npages; i++) { c->type = n->type;
memmove(c->page[i], n->page[i], PGSIZE); if (n->type == ONDEMAND) {
c->ip = idup(n->ip);
c->offset = n->offset;
c->sz = c->sz;
}
if (n->page[0]) { // If the first page is present, all of them are present
if (vmn_doallocpg(c) < 0) {
panic("vmn_copy\n");
}
for(uint i = 0; i < n->npages; i++) {
memmove(c->page[i], n->page[i], PGSIZE);
}
} }
} }
return c; return c;
...@@ -554,12 +568,12 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err) ...@@ -554,12 +568,12 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
if(m == 0) if(m == 0)
return -1; return -1;
// cprintf("%d: pf addr=0x%x err 0x%x\n", proc->pid, va, err); // cprintf("%d: pf addr=0x%x err 0x%x\n", proc->pid, va, err);
// cprintf("%d: pf vma type = %d refcnt %d vmn type %d pte=0x%x\n", proc->pid, m->va_type, m->n->ref, m->n->type, *pte); // cprintf("%d: pf vma type = %d refcnt %d vmn type %d pte=0x%x\n", proc->pid, m->va_type, m->n->ref, m->n->type, *pte);
uint npg = (PGROUNDDOWN(va) - m->va_start) / PGSIZE; uint npg = (PGROUNDDOWN(va) - m->va_start) / PGSIZE;
if (m->n && m->n->ip && *pte == 0x0) { if (m->n && m->n->ip && *pte == 0x0 && m->n->page[npg] == 0) {
//cprintf("ODP\n"); // cprintf("ODP\n");
if (vmn_doallocpg(m->n) < 0) { if (vmn_doallocpg(m->n) < 0) {
panic("pagefault: couldn't allocate pages"); panic("pagefault: couldn't allocate pages");
} }
...@@ -571,7 +585,7 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err) ...@@ -571,7 +585,7 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
pte = walkpgdir(pgdir, (const void *)va, 0); pte = walkpgdir(pgdir, (const void *)va, 0);
if (pte == 0x0) if (pte == 0x0)
panic("pagefault: not paged in???"); panic("pagefault: not paged in???");
cprintf("ODP done\n"); // cprintf("ODP done\n");
} }
if (m->va_type == COW && (err & FEC_WR)) { if (m->va_type == COW && (err & FEC_WR)) {
...@@ -606,6 +620,3 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err) ...@@ -606,6 +620,3 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
release(&m->lock); release(&m->lock);
return 1; return 1;
} }
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论