proc_pgmaps must be rcu_freed, and pgmap_list_.enumerate must have scoped_gc_epoch

上级 277f2b6c
...@@ -20,12 +20,13 @@ struct pgmap; ...@@ -20,12 +20,13 @@ struct pgmap;
} }
#endif #endif
struct proc_pgmap : public referenced { struct proc_pgmap : public referenced, public rcu_freed {
pgmap* const pml4; pgmap* const pml4;
vmap* const vmp; vmap* const vmp;
static proc_pgmap* alloc(vmap* vmap); static proc_pgmap* alloc(vmap* vmap);
virtual void onzero() const { delete this; } virtual void onzero() const;
virtual void do_gc(void) { delete this; }
proc_pgmap& operator=(const proc_pgmap&) = delete; proc_pgmap& operator=(const proc_pgmap&) = delete;
proc_pgmap(const proc_pgmap& x) = delete; proc_pgmap(const proc_pgmap& x) = delete;
private: private:
......
...@@ -31,7 +31,7 @@ struct kstack_tag kstack_tag[NCPU]; ...@@ -31,7 +31,7 @@ struct kstack_tag kstack_tag[NCPU];
enum { sched_debug = 0 }; enum { sched_debug = 0 };
proc_pgmap::proc_pgmap(vmap* vmap) proc_pgmap::proc_pgmap(vmap* vmap)
: pml4(setupkvm()), vmp(vmap) : rcu_freed("proc_pgmap"), pml4(setupkvm()), vmp(vmap)
{ {
if (pml4 == nullptr) { if (pml4 == nullptr) {
cprintf("proc_pgmap::proc_pgmap: setupkvm out of memory\n"); cprintf("proc_pgmap::proc_pgmap: setupkvm out of memory\n");
...@@ -50,11 +50,18 @@ proc_pgmap::alloc(vmap* vmap) ...@@ -50,11 +50,18 @@ proc_pgmap::alloc(vmap* vmap)
proc_pgmap::~proc_pgmap(void) proc_pgmap::~proc_pgmap(void)
{ {
vmp->rem_pgmap(this);
vmp->decref();
freevm(pml4); freevm(pml4);
} }
void
proc_pgmap::onzero() const
{
proc_pgmap* p = (proc_pgmap*) this;
p->vmp->rem_pgmap(p);
p->vmp->decref();
gc_delayed(p);
}
proc::proc(int npid) : proc::proc(int npid) :
rcu_freed("proc"), vmap(0), uwq(0), worker(0), kstack(0), rcu_freed("proc"), vmap(0), uwq(0), worker(0), kstack(0),
pid(npid), parent(0), tf(0), context(0), killed(0), pid(npid), parent(0), tf(0), context(0), killed(0),
......
...@@ -487,14 +487,15 @@ again: ...@@ -487,14 +487,15 @@ again:
}; };
if (replaced) { if (replaced) {
if (updateall) if (updateall) {
scoped_gc_epoch gc;
pgmap_list_.enumerate([&](proc_pgmap* const &p, pgmap_list_.enumerate([&](proc_pgmap* const &p,
proc_pgmap* const &x)->bool proc_pgmap* const &x)->bool
{ {
updatepages(p->pml4, e->vma_start, e->vma_end, update); updatepages(p->pml4, e->vma_start, e->vma_end, update);
return false; return false;
}); });
else } else
updatepages(pgmap->pml4, e->vma_start, e->vma_end, update); updatepages(pgmap->pml4, e->vma_start, e->vma_end, update);
} }
...@@ -558,14 +559,15 @@ vmap::remove(uptr vma_start, uptr len, proc_pgmap* pgmap) ...@@ -558,14 +559,15 @@ vmap::remove(uptr vma_start, uptr len, proc_pgmap* pgmap)
} }
}; };
if (updateall) if (updateall) {
scoped_gc_epoch gc;
pgmap_list_.enumerate([&](proc_pgmap* const &p, pgmap_list_.enumerate([&](proc_pgmap* const &p,
proc_pgmap* const &x)->bool proc_pgmap* const &x)->bool
{ {
updatepages(p->pml4, vma_start, vma_start + len, update); updatepages(p->pml4, vma_start, vma_start + len, update);
return false; return false;
}); });
else } else
updatepages(pgmap->pml4, vma_start, vma_start + len, update); updatepages(pgmap->pml4, vma_start, vma_start + len, update);
if (tlb_shootdown && needtlb) { if (tlb_shootdown && needtlb) {
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论