summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/platform/filemem
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2018-09-10 15:22:44 -0700
committerShentubot <shentubot@google.com>2018-09-10 15:23:44 -0700
commita29c39aa629b6118765e5075eb228752934d7081 (patch)
treec9270c0fff94e8f19310aaa26c08081cdaf76dcf /pkg/sentry/platform/filemem
parent7e9e6745ca1f17031bbea14cb08b3ee3c0f9f818 (diff)
Map committed chunks concurrently in FileMem.LoadFrom.
PiperOrigin-RevId: 212345401 Change-Id: Iac626ee87ba312df88ab1019ade6ecd62c04c75c
Diffstat (limited to 'pkg/sentry/platform/filemem')
-rw-r--r--pkg/sentry/platform/filemem/filemem_state.go24
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 {