diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/sentry/platform/filemem/filemem_state.go | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/pkg/sentry/platform/filemem/filemem_state.go b/pkg/sentry/platform/filemem/filemem_state.go index 5dace8fec..e28e021c9 100644 --- a/pkg/sentry/platform/filemem/filemem_state.go +++ b/pkg/sentry/platform/filemem/filemem_state.go @@ -19,6 +19,7 @@ import ( "fmt" "io" "runtime" + "sync/atomic" "syscall" "gvisor.googlesource.com/gvisor/pkg/log" @@ -127,6 +128,29 @@ func (f *FileMem) LoadFrom(r io.Reader) error { return err } + // Try to map committed chunks concurrently: For any given chunk, either + // this loop or the following one will mmap the chunk first and cache it in + // f.mappings for the other, but this loop is likely to run ahead of the + // other since it doesn't do any work between mmaps. The rest of this + // function doesn't mutate f.usage, so it's safe to iterate concurrently. + mapperDone := make(chan struct{}) + mapperCanceled := int32(0) + go func() { // S/R-SAFE: see comment + defer func() { close(mapperDone) }() + for seg := f.usage.FirstSegment(); seg.Ok(); seg = seg.NextSegment() { + if atomic.LoadInt32(&mapperCanceled) != 0 { + return + } + if seg.Value().knownCommitted { + f.forEachMappingSlice(seg.Range(), func(s []byte) {}) + } + } + }() + defer func() { + atomic.StoreInt32(&mapperCanceled, 1) + <-mapperDone + }() + // Load committed pages. for seg := f.usage.FirstSegment(); seg.Ok(); seg = seg.NextSegment() { if !seg.Value().knownCommitted { |