提交 d1f78e45 创建 作者: Robert Morris's avatar Robert Morris

Merge branch 'scale' of git+ssh://pdos.csail.mit.edu/home/am0/6.828/xv6 into scale

...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define NDEV 10 // maximum major device number #define NDEV 10 // maximum major device number
#define ROOTDEV 1 // device number of file system root disk #define ROOTDEV 1 // device number of file system root disk
#define USERTOP 0xA0000 // end of user address space #define USERTOP 0xA0000 // end of user address space
#define PHYSTOP 0x4000000 // use phys mem up to here as free pool #define PHYSTOP 0x1000000 // use phys mem up to here as free pool
#define MAXARG 32 // max exec arguments #define MAXARG 32 // max exec arguments
#define MAXNAME 16 // max string names #define MAXNAME 16 // max string names
#define MINCYCTHRESH 1000000 // min cycles a proc executes on a core before allowed to be stolen #define MINCYCTHRESH 1000000 // min cycles a proc executes on a core before allowed to be stolen
...@@ -261,7 +261,7 @@ fork(int flags) ...@@ -261,7 +261,7 @@ fork(int flags)
{ {
int i, pid; int i, pid;
struct proc *np; struct proc *np;
uint cow = 0; uint cow = 1;
// cprintf("%d: fork\n", proc->pid); // cprintf("%d: fork\n", proc->pid);
......
...@@ -369,9 +369,10 @@ vmap_alloc(void) ...@@ -369,9 +369,10 @@ vmap_alloc(void)
static void static void
vmap_free(struct vmap *m) vmap_free(struct vmap *m)
{ {
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) {
if(m->e[i].n) if(m->e[i].n)
vmn_decref(m->e[i].n); vmn_decref(m->e[i].n);
}
freevm(m->pgdir); freevm(m->pgdir);
m->pgdir = 0; m->pgdir = 0;
m->alloc = 0; m->alloc = 0;
...@@ -449,7 +450,7 @@ vmap_remove(struct vmap *m, uint va_start, uint len) ...@@ -449,7 +450,7 @@ vmap_remove(struct vmap *m, uint va_start, uint len)
return -1; return -1;
} }
__sync_fetch_and_sub(&m->e[i].n->ref, 1); __sync_fetch_and_sub(&m->e[i].n->ref, 1); // XXX shouldn't use vmn_decref?
m->e[i].n = 0; m->e[i].n = 0;
} }
} }
...@@ -624,22 +625,19 @@ pagefault_ondemand(struct vmap *vmap, uint va, uint err, struct vma *m) ...@@ -624,22 +625,19 @@ pagefault_ondemand(struct vmap *vmap, uint va, uint err, struct vma *m)
static void static void
pagefault_wcow(struct vmap *vmap, uint va, pte_t *pte, struct vma *m, uint npg) pagefault_wcow(struct vmap *vmap, uint va, pte_t *pte, struct vma *m, uint npg)
{ {
if (m->n->ref == 1) { // if vma isn't shared any more, make it private // Always make a copy of n, even if this process has the only ref, because other processes
m->va_type = PRIVATE; // may change ref count while this process is handling wcow
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W; struct vmnode *o = m->n;
} else { // vma is still shared; give process its private copy struct vmnode *c = vmn_copy(m->n);
struct vmnode *c = vmn_copy(m->n); c->ref = 1;
c->ref = 1; m->va_type = PRIVATE;
__sync_sub_and_fetch(&m->n->ref, 1); m->n = c;
if (m->n->ref == 0) // Update the hardware page tables to reflect the change to the vma
panic("cow"); clearpages(vmap->pgdir, (void *) m->va_start, (void *) m->va_end);
m->va_type = PRIVATE; pte = walkpgdir(vmap->pgdir, (const void *)va, 0);
m->n = c; *pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
// Update the hardware page tables to reflect the change to the vma // drop my ref to vmnode
clearpages(vmap->pgdir, (void *) m->va_start, (void *) m->va_end); vmn_decref(o);
pte = walkpgdir(vmap->pgdir, (const void *)va, 0);
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
}
} }
int int
...@@ -661,8 +659,9 @@ pagefault(struct vmap *vmap, uint va, uint err) ...@@ -661,8 +659,9 @@ pagefault(struct vmap *vmap, uint va, uint err)
} else if (m->va_type == COW) { } else if (m->va_type == COW) {
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_COW; *pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_COW;
} else { } else {
if (m->n->ref > 1) if (m->n->ref != 1) {
panic("pagefault"); panic("pagefault");
}
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W; *pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
} }
lcr3(PADDR(vmap->pgdir)); // Reload hardware page tables lcr3(PADDR(vmap->pgdir)); // Reload hardware page tables
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论