diff options
author | Adin Scannell <ascannell@google.com> | 2020-02-25 12:21:27 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-02-25 12:22:29 -0800 |
commit | 98b693e61b37a62f7b29ce1cab8b4c4c54fa044e (patch) | |
tree | 78bb75c7a04f7272876d0d650e5a4be240b31445 /pkg/sentry | |
parent | 53504e29ca27b8dc9e098fbb88983fdbce90cca3 (diff) |
Don't acquire contended lock with the OS thread locked.
Fixes #1049
PiperOrigin-RevId: 297175164
Diffstat (limited to 'pkg/sentry')
-rw-r--r-- | pkg/sentry/platform/kvm/machine.go | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index 8076c7529..f1afc74dc 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -329,10 +329,12 @@ func (m *machine) Destroy() { } // Get gets an available vCPU. +// +// This will return with the OS thread locked. func (m *machine) Get() *vCPU { + m.mu.RLock() runtime.LockOSThread() tid := procid.Current() - m.mu.RLock() // Check for an exact match. if c := m.vCPUs[tid]; c != nil { @@ -343,8 +345,22 @@ func (m *machine) Get() *vCPU { // The happy path failed. We now proceed to acquire an exclusive lock // (because the vCPU map may change), and scan all available vCPUs. + // In this case, we first unlock the OS thread. Otherwise, if mu is + // not available, the current system thread will be parked and a new + // system thread spawned. We avoid this situation by simply refreshing + // tid after relocking the system thread. m.mu.RUnlock() + runtime.UnlockOSThread() m.mu.Lock() + runtime.LockOSThread() + tid = procid.Current() + + // Recheck for an exact match. + if c := m.vCPUs[tid]; c != nil { + c.lock() + m.mu.Unlock() + return c + } for { // Scan for an available vCPU. |