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

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