Fix uwq code that want to hold a lock during TLB shootdown

上级 b710d526
...@@ -60,9 +60,9 @@ private: ...@@ -60,9 +60,9 @@ private:
filetable* ftable_; filetable* ftable_;
uwq_ipcbuf* ipc_; uwq_ipcbuf* ipc_;
uptr uentry_; uptr uentry_;
uptr ustack_; std::atomic<uptr> ustack_;
std::atomic<u64> uref_; std::atomic<u64> uref_;
uwq_worker* worker_[NWORKERS]; std::atomic<uwq_worker*> worker_[NWORKERS];
}; };
#endif #endif
...@@ -170,19 +170,15 @@ uwq::haswork(void) const ...@@ -170,19 +170,15 @@ uwq::haswork(void) const
bool bool
uwq::tryworker(void) uwq::tryworker(void)
{ {
// Try to start a worker thread
scoped_acquire lock0(&lock_);
if (!valid()) if (!valid())
return false; return false;
int slot = -1; // Try to start a worker thread
scoped_acquire lock0(&lock_);
for (int i = 0; i < NWORKERS; i++) { for (int i = 0; i < NWORKERS; i++) {
if (worker_[i] == nullptr) { if (worker_[i] == nullptr)
if (slot == -1)
slot = i;
continue; continue;
}
uwq_worker *w = worker_[i]; uwq_worker *w = worker_[i];
if (w->running_) if (w->running_)
...@@ -200,8 +196,15 @@ uwq::tryworker(void) ...@@ -200,8 +196,15 @@ uwq::tryworker(void)
return true; return true;
} }
} }
lock0.release();
again:
u64 uref = uref_.load();
if (uref < ipc_->maxworkers) {
if (!cmpxch(&uref_, uref, uref+1))
goto again;
// Guaranteed to have slot in worker_
if (slot != -1 && uref_ < ipc_->maxworkers) {
proc* p = allocworker(); proc* p = allocworker();
if (p != nullptr) { if (p != nullptr) {
uwq_worker* w = new uwq_worker(this, p); uwq_worker* w = new uwq_worker(this, p);
...@@ -216,12 +219,16 @@ uwq::tryworker(void) ...@@ -216,12 +219,16 @@ uwq::tryworker(void)
addrun(p); addrun(p);
release(&p->lock); release(&p->lock);
worker_[slot] = w; for (int i = 0; i < NWORKERS; i++) {
if (worker_[i] == nullptr)
if (cmpxch(&worker_[i], (uwq_worker*)nullptr, w))
return true; return true;
} }
panic("uwq::tryworker: oops");
}
} }
return nullptr; return false;
} }
void void
...@@ -283,14 +290,14 @@ uwq::allocworker(void) ...@@ -283,14 +290,14 @@ uwq::allocworker(void)
return nullptr; return nullptr;
} }
uptr stacktop = ustack_ + (USTACKPAGES*PGSIZE); // Include a bumper page
if (vmap_->insert(vmn, ustack_, 1) < 0) { uptr ustack = ustack_.fetch_add((USTACKPAGES*PGSIZE)+PGSIZE);
uptr stacktop = ustack + (USTACKPAGES*PGSIZE);
if (vmap_->insert(vmn, ustack, 1) < 0) {
delete vmn; delete vmn;
finishproc(p); finishproc(p);
return nullptr; return nullptr;
} }
// Include a bumper page
ustack_ += (USTACKPAGES*PGSIZE)+PGSIZE;
p->tf->rsp = stacktop - 8; p->tf->rsp = stacktop - 8;
p->tf->rip = uentry; p->tf->rip = uentry;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论