Some vm tweaks to help track down a bug in uwq, or one that uwq tickles

上级 a10f9aa2
...@@ -20,7 +20,6 @@ enum vmntype { EAGER, ONDEMAND }; ...@@ -20,7 +20,6 @@ enum vmntype { EAGER, ONDEMAND };
struct vmnode { struct vmnode {
const u64 npages; const u64 npages;
atomic<char*> page[128]; atomic<char*> page[128];
atomic<u64> ref;
const enum vmntype type; const enum vmntype type;
struct inode *const ip; struct inode *const ip;
const u64 offset; const u64 offset;
...@@ -30,11 +29,15 @@ struct vmnode { ...@@ -30,11 +29,15 @@ struct vmnode {
inode *i = 0, u64 off = 0, u64 s = 0); inode *i = 0, u64 off = 0, u64 s = 0);
~vmnode(); ~vmnode();
void decref(); void decref();
void incref();
u64 ref();
int allocpg(); int allocpg();
vmnode* copy(); vmnode* copy();
int demand_load(); int demand_load();
NEW_DELETE_OPS(vmnode) NEW_DELETE_OPS(vmnode);
private:
atomic<u64> ref_;
}; };
// A mapping of a chunk of an address space to // A mapping of a chunk of an address space to
......
...@@ -23,7 +23,7 @@ enum { vm_debug = 0 }; ...@@ -23,7 +23,7 @@ enum { vm_debug = 0 };
*/ */
vmnode::vmnode(u64 npg, vmntype ntype, inode *i, u64 off, u64 s) vmnode::vmnode(u64 npg, vmntype ntype, inode *i, u64 off, u64 s)
: npages(npg), ref(0), type(ntype), ip(i), offset(off), sz(s) : npages(npg), type(ntype), ip(i), offset(off), sz(s), ref_(0)
{ {
if (npg > NELEM(page)) if (npg > NELEM(page))
panic("vmnode too big\n"); panic("vmnode too big\n");
...@@ -44,12 +44,24 @@ vmnode::~vmnode() ...@@ -44,12 +44,24 @@ vmnode::~vmnode()
} }
void void
vmnode::decref() vmnode::decref(void)
{ {
if(--ref == 0) if(--ref_ == 0)
delete this; delete this;
} }
void
vmnode::incref(void)
{
++ref_;
}
u64
vmnode::ref(void)
{
return ref_.load();
}
int int
vmnode::allocpg() vmnode::allocpg()
{ {
...@@ -126,7 +138,7 @@ vma::vma(vmap *vmap, uptr start, uptr end, enum vmatype vtype, vmnode *vmn) : ...@@ -126,7 +138,7 @@ vma::vma(vmap *vmap, uptr start, uptr end, enum vmatype vtype, vmnode *vmn) :
vma_start(start), vma_end(end), va_type(vtype), n(vmn) vma_start(start), vma_end(end), va_type(vtype), n(vmn)
{ {
if (n) if (n)
n->ref++; n->incref();
} }
vma::~vma() vma::~vma()
...@@ -524,7 +536,7 @@ vmap::pagefault(uptr va, u32 err) ...@@ -524,7 +536,7 @@ vmap::pagefault(uptr va, u32 err)
u64 npg = (PGROUNDDOWN(va) - m->vma_start) / PGSIZE; u64 npg = (PGROUNDDOWN(va) - m->vma_start) / PGSIZE;
if (vm_debug) if (vm_debug)
cprintf("pagefault: err 0x%x va 0x%lx type %d ref %lu pid %d\n", cprintf("pagefault: err 0x%x va 0x%lx type %d ref %lu pid %d\n",
err, va, m->va_type, m->n->ref.load(), myproc()->pid); err, va, m->va_type, m->n->ref(), myproc()->pid);
if (m->n && !m->n->page[npg]) if (m->n && !m->n->page[npg])
if (m->n->allocpg() < 0) if (m->n->allocpg() < 0)
...@@ -553,7 +565,8 @@ vmap::pagefault(uptr va, u32 err) ...@@ -553,7 +565,8 @@ vmap::pagefault(uptr va, u32 err)
if (m->va_type == COW) { if (m->va_type == COW) {
*pte = v2p(m->n->page[npg]) | PTE_P | PTE_U | PTE_COW; *pte = v2p(m->n->page[npg]) | PTE_P | PTE_U | PTE_COW;
} else { } else {
assert(m->n->ref == 1); if (m->n->ref() != 1)
panic("vmap::pagefault: ref %lu va %lx", m->n->ref(), va);
*pte = v2p(m->n->page[npg]) | PTE_P | PTE_U | PTE_W; *pte = v2p(m->n->page[npg]) | PTE_P | PTE_U | PTE_W;
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论