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

clean up code

keep the panics for now
上级 eda2be67
...@@ -125,6 +125,7 @@ exec(char *path, char **argv) ...@@ -125,6 +125,7 @@ exec(char *path, char **argv)
switchuvm(proc); switchuvm(proc);
vmap_decref(oldvmap); vmap_decref(oldvmap);
// XXX migrate to another core??
return 0; return 0;
bad: bad:
......
...@@ -295,7 +295,7 @@ vmn_allocpg(uint npg) ...@@ -295,7 +295,7 @@ vmn_allocpg(uint npg)
{ {
struct vmnode *n = vmn_alloc(npg, EAGER); struct vmnode *n = vmn_alloc(npg, EAGER);
if (n == 0) return 0; if (n == 0) return 0;
if (vmn_doallocpg(n) < 0) return 0; if (vmn_doallocpg(n) < 0) return 0; // XXX free n
return n; return n;
} }
...@@ -585,66 +585,62 @@ copyin(struct vmap *vmap, uint va, void *p, uint len) ...@@ -585,66 +585,62 @@ copyin(struct vmap *vmap, uint va, void *p, uint len)
return 0; return 0;
} }
static struct vma *
pagefault_ondemand(struct vmap *vmap, uint va, uint err, struct vma *m)
{
if (vmn_doallocpg(m->n) < 0) {
panic("pagefault: couldn't allocate pages");
}
release(&m->lock);
if (vmn_doload(m->n, m->n->ip, m->n->offset, m->n->sz) < 0) {
panic("pagefault: couldn't load");
}
m = vmap_lookup(vmap, va); // re-acquire lock on m
return m;
}
static void
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
m->va_type = PRIVATE;
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
} else { // vma is still shared; give process its private copy
struct vmnode *c = vmn_copy(m->n);
c->ref = 1;
__sync_sub_and_fetch(&m->n->ref, 1);
if (m->n->ref == 0)
panic("cow");
m->va_type = PRIVATE;
m->n = c;
// Update the hardware page tables to reflect the change to the vma
clearpages(vmap->pgdir, (void *) m->va_start, (void *) m->va_end);
pte = walkpgdir(vmap->pgdir, (const void *)va, 0);
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
}
}
int int
pagefault(struct vmap *vmap, uint va, uint err) pagefault(struct vmap *vmap, uint va, uint err)
{ {
pte_t *pte = walkpgdir(vmap->pgdir, (const void *)va, 1); pte_t *pte = walkpgdir(vmap->pgdir, (const void *)va, 1);
if((*pte & (PTE_P|PTE_U|PTE_W)) == (PTE_P|PTE_U|PTE_W)) if((*pte & (PTE_P|PTE_U|PTE_W)) == (PTE_P|PTE_U|PTE_W))
return 0; return 0;
struct vma *m = vmap_lookup(vmap, va); struct vma *m = vmap_lookup(vmap, va);
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 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 && m->n->page[npg] == 0) { if (m->n && m->n->type == ONDEMAND && m->n->page[npg] == 0) {
// cprintf("ODP\n"); m = pagefault_ondemand(vmap, va, err, m);
if (vmn_doallocpg(m->n) < 0) {
panic("pagefault: couldn't allocate pages");
}
release(&m->lock);
if (vmn_doload(m->n, m->n->ip, m->n->offset, m->n->sz) < 0) {
panic("pagefault: couldn't load");
}
acquire(&m->lock);
pte = walkpgdir(vmap->pgdir, (const void *)va, 0);
if (pte == 0x0)
panic("pagefault: not paged in???");
// cprintf("ODP done\n");
} }
if (m->va_type == COW && (err & FEC_WR)) { if (m->va_type == COW && (err & FEC_WR)) {
// Write to a COW page pagefault_wcow(vmap, va, pte, m, npg);
// cprintf("write to cow\n");
if (m->n->ref == 1) { // if vma isn't shared any more, make it private
m->va_type = PRIVATE;
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
} else { // vma is still shared; give process its private copy
struct vmnode *c = vmn_copy(m->n);
c->ref = 1;
__sync_sub_and_fetch(&m->n->ref, 1);
if (m->n->ref == 0)
panic("cow");
m->va_type = PRIVATE;
m->n = c;
// Update the hardware page tables to reflect the change to the vma
clearpages(vmap->pgdir, (void *) m->va_start, (void *) m->va_end);
pte = walkpgdir(vmap->pgdir, (const void *)va, 0);
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
}
} else if (m->va_type == COW) { } else if (m->va_type == COW) {
// cprintf("cow\n");
*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 {
// cprintf("fill in pte\n"); if (m->n->ref > 1)
if (m->n->ref > 1) {
cprintf("pagefault: va 0x%x\n", va);
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论