mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Protect PCIDs with a mutex.
Because the Drop method may be called across vCPUs, it is necessary to protect the PCID database with a mutex to prevent concurrent modification. The PCID is assigned prior to entersyscall, so it's safe to block. PiperOrigin-RevId: 207992864 Change-Id: I8b36d55106981f51e30dcf03e12886330bb79d67
This commit is contained in:
@@ -16,6 +16,10 @@
|
||||
|
||||
package pagetables
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// limitPCID is the number of valid PCIDs.
|
||||
const limitPCID = 4096
|
||||
|
||||
@@ -24,6 +28,9 @@ const limitPCID = 4096
|
||||
// This is not protected by locks and is thus suitable for use only with a
|
||||
// single CPU at a time.
|
||||
type PCIDs struct {
|
||||
// mu protects below.
|
||||
mu sync.Mutex
|
||||
|
||||
// cache are the assigned page tables.
|
||||
cache map[*PageTables]uint16
|
||||
|
||||
@@ -56,7 +63,9 @@ func NewPCIDs(start, size uint16) *PCIDs {
|
||||
// This may overwrite any previous assignment provided. If this in the case,
|
||||
// true is returned to indicate that the PCID should be flushed.
|
||||
func (p *PCIDs) Assign(pt *PageTables) (uint16, bool) {
|
||||
p.mu.Lock()
|
||||
if pcid, ok := p.cache[pt]; ok {
|
||||
p.mu.Unlock()
|
||||
return pcid, false // No flush.
|
||||
}
|
||||
|
||||
@@ -68,6 +77,7 @@ func (p *PCIDs) Assign(pt *PageTables) (uint16, bool) {
|
||||
|
||||
// We need to flush because while this is in the available
|
||||
// pool, it may have been used previously.
|
||||
p.mu.Unlock()
|
||||
return pcid, true
|
||||
}
|
||||
|
||||
@@ -79,17 +89,21 @@ func (p *PCIDs) Assign(pt *PageTables) (uint16, bool) {
|
||||
// A flush is definitely required in this case, these page
|
||||
// tables may still be active. (They will just be assigned some
|
||||
// other PCID if and when they hit the given CPU again.)
|
||||
p.mu.Unlock()
|
||||
return pcid, true
|
||||
}
|
||||
|
||||
// No PCID.
|
||||
p.mu.Unlock()
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Drop drops references to a set of page tables.
|
||||
func (p *PCIDs) Drop(pt *PageTables) {
|
||||
p.mu.Lock()
|
||||
if pcid, ok := p.cache[pt]; ok {
|
||||
delete(p.cache, pt)
|
||||
p.avail = append(p.avail, pcid)
|
||||
}
|
||||
p.mu.Unlock()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user