KVM machine.Get(): Use up vCPU pool before scanning for available ones.

Previously, we created vCPUs on demand, and so taking an unused vCPU from the
pool was expensive. Now, we pre-create all vCPUs at the start, so it makes
sense to use them all to reduce contention.

PiperOrigin-RevId: 448382485
This commit is contained in:
Konstantin Bogomolov 2022-05-12 18:09:34 -07:00 committed by gVisor bot
parent d4652bd6df
commit db16575cb5
1 changed files with 12 additions and 12 deletions

View File

@ -476,18 +476,6 @@ func (m *machine) Get() *vCPU {
} }
for { for {
// Scan for an available vCPU.
for origTID, c := range m.vCPUsByTID {
if c.state.CompareAndSwap(vCPUReady, vCPUUser) {
delete(m.vCPUsByTID, origTID)
m.vCPUsByTID[tid] = c
m.mu.Unlock()
c.loadSegments(tid)
timer.Finish("unused")
return c
}
}
// Get vCPU from the m.vCPUsByID pool. // Get vCPU from the m.vCPUsByID pool.
if m.usedVCPUs < m.maxVCPUs { if m.usedVCPUs < m.maxVCPUs {
c := m.vCPUsByID[m.usedVCPUs] c := m.vCPUsByID[m.usedVCPUs]
@ -500,6 +488,18 @@ func (m *machine) Get() *vCPU {
return c return c
} }
// Scan for an available vCPU.
for origTID, c := range m.vCPUsByTID {
if c.state.CompareAndSwap(vCPUReady, vCPUUser) {
delete(m.vCPUsByTID, origTID)
m.vCPUsByTID[tid] = c
m.mu.Unlock()
c.loadSegments(tid)
timer.Finish("unused")
return c
}
}
// Scan for something not in user mode. // Scan for something not in user mode.
for origTID, c := range m.vCPUsByTID { for origTID, c := range m.vCPUsByTID {
if !c.state.CompareAndSwap(vCPUGuest, vCPUGuest|vCPUWaiter) { if !c.state.CompareAndSwap(vCPUGuest, vCPUGuest|vCPUWaiter) {