diff options
author | Jamie Liu <jamieliu@google.com> | 2018-09-10 15:22:44 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-09-10 15:23:44 -0700 |
commit | a29c39aa629b6118765e5075eb228752934d7081 (patch) | |
tree | c9270c0fff94e8f19310aaa26c08081cdaf76dcf /pkg | |
parent | 7e9e6745ca1f17031bbea14cb08b3ee3c0f9f818 (diff) |
Map committed chunks concurrently in FileMem.LoadFrom.
PiperOrigin-RevId: 212345401
Change-Id: Iac626ee87ba312df88ab1019ade6ecd62c04c75c
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 { |