提交 570214f8 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

separate tlbflush(u64 myreq) function to flush given an older start time

上级 c841ea25
...@@ -13,6 +13,7 @@ pgmap* setupkvm(void); ...@@ -13,6 +13,7 @@ pgmap* setupkvm(void);
int mapkva(pgmap *pml4, char* kva, uptr uva, size_t size); int mapkva(pgmap *pml4, char* kva, uptr uva, size_t size);
std::atomic<pme_t>* walkpgdir(pgmap *pml4, u64, int); std::atomic<pme_t>* walkpgdir(pgmap *pml4, u64, int);
void tlbflush(void); void tlbflush(void);
void tlbflush(u64 req);
template<class CB> template<class CB>
void void
......
...@@ -151,10 +151,13 @@ switchvm(struct proc *p) ...@@ -151,10 +151,13 @@ switchvm(struct proc *p)
mycpu()->ts.rsp[0] = (u64) myproc()->kstack + KSTACKSIZE; mycpu()->ts.rsp[0] = (u64) myproc()->kstack + KSTACKSIZE;
mycpu()->ts.iomba = (u16)__offsetof(struct taskstate, iopb); mycpu()->ts.iomba = (u16)__offsetof(struct taskstate, iopb);
ltr(TSSSEG); ltr(TSSSEG);
u64 nreq = tlbflush_req.load();
if (p->vmap != 0 && p->vmap->pml4 != 0) if (p->vmap != 0 && p->vmap->pml4 != 0)
lcr3(v2p(p->vmap->pml4)); // switch to new address space lcr3(v2p(p->vmap->pml4)); // switch to new address space
else else
switchkvm(); switchkvm();
mycpu()->tlbflush_done = nreq;
writefs(UDSEG); writefs(UDSEG);
writemsr(MSR_FS_BASE, p->user_fs_); writemsr(MSR_FS_BASE, p->user_fs_);
...@@ -224,14 +227,20 @@ void ...@@ -224,14 +227,20 @@ void
tlbflush() tlbflush()
{ {
u64 myreq = tlbflush_req++; u64 myreq = tlbflush_req++;
tlbflush(myreq);
}
void
tlbflush(u64 myreq)
{
// the caller may not hold any spinlock, because other CPUs might // the caller may not hold any spinlock, because other CPUs might
// be spinning waiting for that spinlock, with interrupts disabled, // be spinning waiting for that spinlock, with interrupts disabled,
// so we will deadlock waiting for their TLB flush.. // so we will deadlock waiting for their TLB flush..
assert(mycpu()->ncli == 0); assert(mycpu()->ncli == 0);
for (int i = 0; i < ncpu; i++) for (int i = 0; i < ncpu; i++)
lapic_tlbflush(i); if (cpus[i].tlbflush_done < myreq)
lapic_tlbflush(i);
for (int i = 0; i < ncpu; i++) for (int i = 0; i < ncpu; i++)
while (cpus[i].tlbflush_done < myreq) while (cpus[i].tlbflush_done < myreq)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论