Delete pgalloc.MemoryFileProvider.

The work done in c087777e37 ("Plumb restore context to afterLoad()") makes
pgalloc.MemoryFileProvider redundant as structs can now easily restore
pgalloc.MemoryFile in stateify's afterLoad() method. This allows structs to
have a pgalloc.MemoryFile field and use that directly, instead of going through
the provided interface.

This cleans up a lot of code and also should be more performant (avoids an
interface method call on many hot paths).

PiperOrigin-RevId: 615258927
This commit is contained in:
Ayush Ranjan
2024-03-12 20:06:58 -07:00
committed by gVisor bot
parent 5fd40fc0be
commit ed9678b679
28 changed files with 132 additions and 152 deletions
-7
View File
@@ -116,8 +116,6 @@ func (t *TestContext) Value(key any) any {
return t.l
case pgalloc.CtxMemoryFile:
return t.mf
case pgalloc.CtxMemoryFileProvider:
return t
case platform.CtxPlatform:
return t.platform
case uniqueid.CtxGlobalUniqueID:
@@ -136,11 +134,6 @@ func (t *TestContext) Value(key any) any {
}
}
// MemoryFile implements pgalloc.MemoryFileProvider.MemoryFile.
func (t *TestContext) MemoryFile() *pgalloc.MemoryFile {
return t.mf
}
// RootContext returns a Context that may be used in tests that need root
// credentials. Uses ptrace as the platform.Platform.
func RootContext(tb testing.TB) context.Context {
+10 -10
View File
@@ -183,9 +183,9 @@ type FilesystemType struct{}
type filesystem struct {
vfsfs vfs.Filesystem
// mfp is used to allocate memory that caches regular file contents. mfp is
// mf is used to allocate memory that caches regular file contents. mf is
// immutable.
mfp pgalloc.MemoryFileProvider
mf *pgalloc.MemoryFile `state:"nosave"`
// Immutable options.
opts filesystemOptions
@@ -395,9 +395,9 @@ func (FilesystemType) Release(ctx context.Context) {}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
mfp := pgalloc.MemoryFileProviderFromContext(ctx)
if mfp == nil {
ctx.Warningf("gofer.FilesystemType.GetFilesystem: context does not provide a pgalloc.MemoryFileProvider")
mf := pgalloc.MemoryFileFromContext(ctx)
if mf == nil {
ctx.Warningf("gofer.FilesystemType.GetFilesystem: CtxMemoryFile is nil")
return nil, nil, linuxerr.EINVAL
}
@@ -522,7 +522,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
return nil, nil, err
}
fs := &filesystem{
mfp: mfp,
mf: mf,
opts: fsopts,
iopts: iopts,
clock: ktime.RealtimeClockFromContext(ctx),
@@ -660,7 +660,7 @@ func getFDFromMountOptionsMap(ctx context.Context, mopts map[string]string) (int
func (fs *filesystem) Release(ctx context.Context) {
fs.released.Store(1)
mf := fs.mfp.MemoryFile()
mf := fs.mf
fs.syncMu.Lock()
for elem := fs.syncableDentries.Front(); elem != nil; elem = elem.Next() {
d := elem.d
@@ -1385,7 +1385,7 @@ func (d *dentry) updateSizeAndUnlockDataMuLocked(newSize uint64) {
// truncated pages have been removed from the remote file, they
// should be dropped without being written back.
d.dataMu.Lock()
d.cache.Truncate(newSize, d.fs.mfp.MemoryFile())
d.cache.Truncate(newSize, d.fs.mf)
d.dirty.KeepClean(memmap.MappableRange{newSize, oldpgend})
d.dataMu.Unlock()
}
@@ -1758,7 +1758,7 @@ func (d *dentry) evictLocked(ctx context.Context) {
// destroyDisconnected destroys an uncached, unparented dentry. There are no
// locking preconditions.
func (d *dentry) destroyDisconnected(ctx context.Context) {
mf := d.fs.mfp.MemoryFile()
mf := d.fs.mf
d.handleMu.Lock()
d.dataMu.Lock()
@@ -2080,7 +2080,7 @@ func (d *dentry) syncCachedFile(ctx context.Context, forFilesystemSync bool) err
// Write back dirty pages to the remote file.
d.dataMu.Lock()
h := d.writeHandle()
err := fsutil.SyncDirtyAll(ctx, &d.cache, &d.dirty, d.size.Load(), d.fs.mfp.MemoryFile(), h.writeFromBlocksAt)
err := fsutil.SyncDirtyAll(ctx, &d.cache, &d.dirty, d.size.Load(), d.fs.mf, h.writeFromBlocksAt)
d.dataMu.Unlock()
if err != nil {
return err
+1 -1
View File
@@ -27,7 +27,7 @@ import (
func TestDestroyIdempotent(t *testing.T) {
ctx := contexttest.Context(t)
fs := filesystem{
mfp: pgalloc.MemoryFileProviderFromContext(ctx),
mf: pgalloc.MemoryFileFromContext(ctx),
inoByKey: make(map[inoKey]uint64),
clock: time.RealtimeClockFromContext(ctx),
// Test relies on no dentry being held in the cache.
+9 -9
View File
@@ -309,7 +309,7 @@ func (fd *regularFileFD) writeCache(ctx context.Context, d *dentry, offset int64
d.mapsMu.Unlock()
// Finally free pages removed from the cache.
mf := d.fs.mfp.MemoryFile()
mf := d.fs.mf
for _, freedFR := range freed {
mf.DecRef(freedFR)
}
@@ -374,7 +374,7 @@ func (rw *dentryReadWriter) ReadToBlocks(dsts safemem.BlockSeq) (uint64, error)
}
// Otherwise read from/through the cache.
mf := rw.d.fs.mfp.MemoryFile()
mf := rw.d.fs.mf
fillCache := mf.ShouldCacheEvictable()
var dataMuUnlock func()
if fillCache {
@@ -501,7 +501,7 @@ func (rw *dentryReadWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, erro
}
// Otherwise write to/through the cache.
mf := rw.d.fs.mfp.MemoryFile()
mf := rw.d.fs.mf
rw.d.dataMu.Lock()
// Compute the range to write (overflow-checked).
@@ -608,7 +608,7 @@ func (d *dentry) writeback(ctx context.Context, offset, size int64) error {
return fsutil.SyncDirty(ctx, memmap.MappableRange{
Start: uint64(offset),
End: uint64(end),
}, &d.cache, &d.dirty, dentrySize, d.fs.mfp.MemoryFile(), h.writeFromBlocksAt)
}, &d.cache, &d.dirty, dentrySize, d.fs.mf, h.writeFromBlocksAt)
}
// Seek implements vfs.FileDescriptionImpl.Seek.
@@ -716,7 +716,7 @@ func (d *dentry) AddMapping(ctx context.Context, ms memmap.MappingSpace, ar host
if d.fs.mayCachePagesInMemoryFile() {
// d.Evict() will refuse to evict memory-mapped pages, so tell the
// MemoryFile to not bother trying.
mf := d.fs.mfp.MemoryFile()
mf := d.fs.mf
for _, r := range mapped {
mf.MarkUnevictable(d, pgalloc.EvictableRange{r.Start, r.End})
}
@@ -736,7 +736,7 @@ func (d *dentry) RemoveMapping(ctx context.Context, ms memmap.MappingSpace, ar h
// Pages that are no longer referenced by any application memory
// mappings are now considered unused; allow MemoryFile to evict them
// when necessary.
mf := d.fs.mfp.MemoryFile()
mf := d.fs.mf
d.dataMu.Lock()
for _, r := range unmapped {
// Since these pages are no longer mapped, they are no longer
@@ -792,7 +792,7 @@ func (d *dentry) Translate(ctx context.Context, required, optional memmap.Mappab
optional.End = pgend
}
mf := d.fs.mfp.MemoryFile()
mf := d.fs.mf
h := d.readHandle()
_, cerr := d.cache.Fill(ctx, required, maxFillRange(required, optional), d.size.Load(), mf, usage.PageCache, pgalloc.AllocateAndWritePopulate, h.readToBlocksAt)
@@ -862,7 +862,7 @@ func (d *dentry) InvalidateUnsavable(ctx context.Context) error {
// Write the cache's contents back to the remote file so that if we have a
// host fd after restore, the remote file's contents are coherent.
mf := d.fs.mfp.MemoryFile()
mf := d.fs.mf
d.handleMu.RLock()
defer d.handleMu.RUnlock()
h := d.writeHandle()
@@ -884,7 +884,7 @@ func (d *dentry) InvalidateUnsavable(ctx context.Context) error {
// Evict implements pgalloc.EvictableMemoryUser.Evict.
func (d *dentry) Evict(ctx context.Context, er pgalloc.EvictableRange) {
mr := memmap.MappableRange{er.Start, er.End}
mf := d.fs.mfp.MemoryFile()
mf := d.fs.mf
d.mapsMu.Lock()
defer d.mapsMu.Unlock()
d.handleMu.RLock()
+6
View File
@@ -27,6 +27,7 @@ import (
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
@@ -133,6 +134,11 @@ func (d *dentry) beforeSave() {
}
}
// afterLoad is invoked by stateify.
func (fs *filesystem) afterLoad(ctx goContext.Context) {
fs.mf = pgalloc.MemoryFileFromContext(ctx)
}
// afterLoad is invoked by stateify.
func (d *dentry) afterLoad(goContext.Context) {
d.readFD = atomicbitops.FromInt32(-1)
+11 -15
View File
@@ -50,7 +50,7 @@ type FileDescription struct {
vfs.DentryMetadataFileDescriptionImpl
vfs.NoLockFD
mfp pgalloc.MemoryFileProvider
mf *pgalloc.MemoryFile `state:"nosave"`
rbmf ringsBufferFile
sqemf sqEntriesFile
@@ -95,9 +95,9 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par
vd := vfsObj.NewAnonVirtualDentry("[io_uring]")
defer vd.DecRef(ctx)
mfp := pgalloc.MemoryFileProviderFromContext(ctx)
if mfp == nil {
panic(fmt.Sprintf("context.Context %T lacks non-nil value for key %T", ctx, pgalloc.CtxMemoryFileProvider))
mf := pgalloc.MemoryFileFromContext(ctx)
if mf == nil {
panic(fmt.Sprintf("context.Context %T lacks non-nil value for key %T", ctx, pgalloc.CtxMemoryFile))
}
numSqEntries, ok := roundUpPowerOfTwo(entries)
@@ -123,7 +123,6 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par
numSqEntries*uint32((*linux.IORingIndex)(nil).SizeBytes()))
ringsBufferSize = uint64(hostarch.Addr(ringsBufferSize).MustRoundUp())
mf := mfp.MemoryFile()
memCgID := pgalloc.MemoryCgroupIDFromContext(ctx)
rbfr, err := mf.Allocate(ringsBufferSize, pgalloc.AllocOpts{Kind: usage.Anonymous, MemCgID: memCgID})
if err != nil {
@@ -139,7 +138,7 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par
}
iouringfd := &FileDescription{
mfp: mfp,
mf: mf,
rbmf: ringsBufferFile{
fr: rbfr,
},
@@ -215,18 +214,15 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par
// Release implements vfs.FileDescriptionImpl.Release.
func (fd *FileDescription) Release(ctx context.Context) {
mf := pgalloc.MemoryFileProviderFromContext(ctx).MemoryFile()
mf.DecRef(fd.rbmf.fr)
mf.DecRef(fd.sqemf.fr)
fd.mf.DecRef(fd.rbmf.fr)
fd.mf.DecRef(fd.sqemf.fr)
}
// mapSharedBuffers caches internal mappings for the ring's shared memory
// regions.
func (fd *FileDescription) mapSharedBuffers() error {
mf := fd.mfp.MemoryFile()
// Mapping for the IORings header struct.
rb, err := mf.MapInternal(fd.rbmf.fr, hostarch.ReadWrite)
rb, err := fd.mf.MapInternal(fd.rbmf.fr, hostarch.ReadWrite)
if err != nil {
return err
}
@@ -242,7 +238,7 @@ func (fd *FileDescription) mapSharedBuffers() error {
fd.cqesBuf.init(cqes)
// Mapping for the SQEs array.
sqes, err := mf.MapInternal(fd.sqemf.fr, hostarch.ReadWrite)
sqes, err := fd.mf.MapInternal(fd.sqemf.fr, hostarch.ReadWrite)
if err != nil {
return err
}
@@ -572,7 +568,7 @@ func (sqemf *sqEntriesFile) Translate(ctx context.Context, required, optional me
return []memmap.Translation{
{
Source: source,
File: pgalloc.MemoryFileProviderFromContext(ctx).MemoryFile(),
File: pgalloc.MemoryFileFromContext(ctx),
Offset: sqemf.fr.Start + source.Start,
Perms: at,
},
@@ -618,7 +614,7 @@ func (rbmf *ringsBufferFile) Translate(ctx context.Context, required, optional m
return []memmap.Translation{
{
Source: source,
File: pgalloc.MemoryFileProviderFromContext(ctx).MemoryFile(),
File: pgalloc.MemoryFileFromContext(ctx),
Offset: rbmf.fr.Start + source.Start,
Perms: at,
},
@@ -14,7 +14,11 @@
package iouringfs
import "context"
import (
"context"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
)
// beforeSave is invoked by stateify.
func (fd *FileDescription) beforeSave() {
@@ -24,7 +28,8 @@ func (fd *FileDescription) beforeSave() {
}
// afterLoad is invoked by stateify.
func (fd *FileDescription) afterLoad(context.Context) {
func (fd *FileDescription) afterLoad(ctx context.Context) {
fd.mf = pgalloc.MemoryFileFromContext(ctx)
// Remap shared buffers.
fd.remap = true
fd.runC = make(chan struct{}, 1)
+3 -3
View File
@@ -77,13 +77,13 @@ func Boot() (*kernel.Kernel, error) {
k.SetMemoryFile(mf)
// Pass k as the platform since it is savable, unlike the actual platform.
vdso, err := loader.PrepareVDSO(k)
vdso, err := loader.PrepareVDSO(k.MemoryFile())
if err != nil {
return nil, fmt.Errorf("creating vdso: %v", err)
}
// Create timekeeper.
tk := kernel.NewTimekeeper(k, vdso.ParamPage.FileRange())
tk := kernel.NewTimekeeper(k.MemoryFile(), vdso.ParamPage.FileRange())
tk.SetClocks(time.NewCalibratedClocks())
creds := auth.NewRootCredentials(auth.NewRootUserNamespace())
@@ -129,7 +129,7 @@ func CreateTask(ctx context.Context, name string, tc *kernel.ThreadGroup, mntns
if err != nil {
return nil, err
}
m := mm.NewMemoryManager(k, k, k.SleepForAddressSpaceActivation)
m := mm.NewMemoryManager(k, k.MemoryFile(), k.SleepForAddressSpaceActivation)
m.SetExecutable(ctx, exe)
creds := auth.CredentialsFromContext(ctx)
+1 -1
View File
@@ -134,7 +134,7 @@ type FilesystemOpts struct {
MaxFilenameLen int
// MemoryFile is the memory file that will be used to store file data. If
// this is nil, then MemoryFileProviderFromContext() is used.
// this is nil, then MemoryFileFromContext() is used.
MemoryFile *pgalloc.MemoryFile
// DisableDefaultSizeLimit disables setting a default size limit. In Linux,
+6 -6
View File
@@ -41,8 +41,8 @@ const kcovAreaSizeMax = 10 * 1024 * 1024
// To give the illusion that the data is always up to date, we update the shared
// memory every time before we return to userspace.
type Kcov struct {
// mfp provides application memory. It is immutable after creation.
mfp pgalloc.MemoryFileProvider
// mf stores application memory. It is immutable after creation.
mf *pgalloc.MemoryFile
// mu protects all of the fields below.
mu sync.RWMutex
@@ -74,7 +74,7 @@ type Kcov struct {
// NewKcov creates and returns a Kcov instance.
func (k *Kernel) NewKcov() *Kcov {
return &Kcov{
mfp: k,
mf: k.mf,
}
}
@@ -94,7 +94,7 @@ func (kcov *Kcov) TaskWork(t *Task) {
}
rw := &kcovReadWriter{
mf: kcov.mfp.MemoryFile(),
mf: kcov.mf,
fr: kcov.mappable.FileRange(),
}
@@ -246,7 +246,7 @@ func (kcov *Kcov) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) erro
Kind: usage.Anonymous,
MemCgID: pgalloc.MemoryCgroupIDFromContext(ctx),
}
fr, err := kcov.mfp.MemoryFile().Allocate(kcov.size*8, opts)
fr, err := kcov.mf.Allocate(kcov.size*8, opts)
if err != nil {
return err
}
@@ -258,7 +258,7 @@ func (kcov *Kcov) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) erro
}
// For convenience, a special mappable is used here. Note that these mappings
// will look different under /proc/[pid]/maps than they do on Linux.
kcov.mappable = mm.NewSpecialMappable(fmt.Sprintf("[kcov:%d]", t.ThreadID()), kcov.mfp, fr)
kcov.mappable = mm.NewSpecialMappable(fmt.Sprintf("[kcov:%d]", t.ThreadID()), kcov.mf, fr)
}
kcov.mappable.IncRef()
opts.Mappable = kcov.mappable
+2 -7
View File
@@ -142,8 +142,7 @@ type Kernel struct {
// All of the following fields are immutable unless otherwise specified.
// Platform is the platform that is used to execute tasks in the created
// Kernel. See comment on pgalloc.MemoryFileProvider for why Platform is
// embedded anonymously (the same issue applies).
// Kernel.
platform.Platform `state:"nosave"`
// mf provides application memory.
@@ -894,8 +893,6 @@ func (ctx *createProcessContext) Value(key any) any {
return ctx.getMemoryCgroupID()
case pgalloc.CtxMemoryFile:
return ctx.kernel.mf
case pgalloc.CtxMemoryFileProvider:
return ctx.kernel
case platform.CtxPlatform:
return ctx.kernel
case uniqueid.CtxGlobalUniqueID:
@@ -1533,7 +1530,7 @@ func (k *Kernel) SetMemoryFile(mf *pgalloc.MemoryFile) {
k.mf = mf
}
// MemoryFile implements pgalloc.MemoryFileProvider.MemoryFile.
// MemoryFile returns the MemoryFile that provides application memory.
func (k *Kernel) MemoryFile() *pgalloc.MemoryFile {
return k.mf
}
@@ -1671,8 +1668,6 @@ func (ctx *supervisorContext) Value(key any) any {
return limits.NewLimitSet()
case pgalloc.CtxMemoryFile:
return ctx.Kernel.mf
case pgalloc.CtxMemoryFileProvider:
return ctx.Kernel
case platform.CtxPlatform:
return ctx.Kernel
case uniqueid.CtxGlobalUniqueID:
+14 -8
View File
@@ -34,6 +34,7 @@
package shm
import (
goContext "context"
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
@@ -201,9 +202,9 @@ func (r *Registry) FindOrCreate(ctx context.Context, pid int32, key ipc.Key, siz
//
// Precondition: Caller must hold r.mu.
func (r *Registry) newShmLocked(ctx context.Context, pid int32, key ipc.Key, creator *auth.Credentials, mode linux.FileMode, size uint64) (*Shm, error) {
mfp := pgalloc.MemoryFileProviderFromContext(ctx)
if mfp == nil {
panic(fmt.Sprintf("context.Context %T lacks non-nil value for key %T", ctx, pgalloc.CtxMemoryFileProvider))
mf := pgalloc.MemoryFileFromContext(ctx)
if mf == nil {
panic(fmt.Sprintf("context.Context %T lacks non-nil value for key %T", ctx, pgalloc.CtxMemoryFile))
}
devID, ok := deviceIDFromContext(ctx)
if !ok {
@@ -211,13 +212,13 @@ func (r *Registry) newShmLocked(ctx context.Context, pid int32, key ipc.Key, cre
}
effectiveSize := uint64(hostarch.Addr(size).MustRoundUp())
fr, err := mfp.MemoryFile().Allocate(effectiveSize, pgalloc.AllocOpts{Kind: usage.Anonymous, MemCgID: pgalloc.MemoryCgroupIDFromContext(ctx)})
fr, err := mf.Allocate(effectiveSize, pgalloc.AllocOpts{Kind: usage.Anonymous, MemCgID: pgalloc.MemoryCgroupIDFromContext(ctx)})
if err != nil {
return nil, err
}
shm := &Shm{
mfp: mfp,
mf: mf,
registry: r,
devID: devID,
size: size,
@@ -331,7 +332,7 @@ type Shm struct {
// via MappingIdentity.
ShmRefs
mfp pgalloc.MemoryFileProvider
mf *pgalloc.MemoryFile `state:"nosave"`
// registry points to the shm registry containing this segment. Immutable.
registry *Registry
@@ -379,6 +380,11 @@ type Shm struct {
pendingDestruction bool
}
// afterLoad is invoked by stateify.
func (s *Shm) afterLoad(ctx goContext.Context) {
s.mf = pgalloc.MemoryFileFromContext(ctx)
}
// ID returns object's ID.
func (s *Shm) ID() ipc.ID {
return s.obj.ID
@@ -436,7 +442,7 @@ func (s *Shm) InodeID() uint64 {
// Precondition: Caller must not hold s.mu.
func (s *Shm) DecRef(ctx context.Context) {
s.ShmRefs.DecRef(func() {
s.mfp.MemoryFile().DecRef(s.fr)
s.mf.DecRef(s.fr)
s.registry.remove(s)
})
}
@@ -498,7 +504,7 @@ func (s *Shm) Translate(ctx context.Context, required, optional memmap.MappableR
return []memmap.Translation{
{
Source: source,
File: s.mfp.MemoryFile(),
File: s.mf,
Offset: s.fr.Start + source.Start,
Perms: hostarch.AnyAccess,
},
-2
View File
@@ -120,8 +120,6 @@ func (t *Task) contextValue(key any, isTaskGoroutine bool) any {
return t.memCgID.Load()
case pgalloc.CtxMemoryFile:
return t.k.mf
case pgalloc.CtxMemoryFileProvider:
return t.k
case platform.CtxPlatform:
return t.k
case shm.CtxDeviceID:
+1 -1
View File
@@ -146,7 +146,7 @@ func (t *Task) Stack() *arch.Stack {
// args.MemoryManager does not need to be set by the caller.
func (k *Kernel) LoadTaskImage(ctx context.Context, args loader.LoadArgs) (*TaskImage, *syserr.Error) {
// Prepare a new user address space to load into.
m := mm.NewMemoryManager(k, k, k.SleepForAddressSpaceActivation)
m := mm.NewMemoryManager(k, k.mf, k.SleepForAddressSpaceActivation)
defer m.DecUsers(ctx)
args.MemoryManager = m
+2 -2
View File
@@ -97,9 +97,9 @@ type Timekeeper struct {
// NewTimekeeper does not take ownership of paramPage.
//
// SetClocks must be called on the returned Timekeeper before it is usable.
func NewTimekeeper(mfp pgalloc.MemoryFileProvider, paramPage memmap.FileRange) *Timekeeper {
func NewTimekeeper(mf *pgalloc.MemoryFile, paramPage memmap.FileRange) *Timekeeper {
t := Timekeeper{
params: NewVDSOParamPage(mfp, paramPage),
params: NewVDSOParamPage(mf, paramPage),
}
t.realtimeClock = &timekeeperClock{tk: &t, c: sentrytime.Realtime}
t.monotonicClock = &timekeeperClock{tk: &t, c: sentrytime.Monotonic}
+3 -3
View File
@@ -53,13 +53,13 @@ func (c *mockClocks) GetTime(id sentrytime.ClockID) (int64, error) {
// SetClocks called.
func stateTestClocklessTimekeeper(tb testing.TB) *Timekeeper {
ctx := contexttest.Context(tb)
mfp := pgalloc.MemoryFileProviderFromContext(ctx)
fr, err := mfp.MemoryFile().Allocate(hostarch.PageSize, pgalloc.AllocOpts{Kind: usage.Anonymous})
mf := pgalloc.MemoryFileFromContext(ctx)
fr, err := mf.Allocate(hostarch.PageSize, pgalloc.AllocOpts{Kind: usage.Anonymous})
if err != nil {
tb.Fatalf("failed to allocate memory: %v", err)
}
return &Timekeeper{
params: NewVDSOParamPage(mfp, fr),
params: NewVDSOParamPage(mf, fr),
}
}
+15 -9
View File
@@ -15,6 +15,7 @@
package kernel
import (
"context"
"fmt"
"gvisor.dev/gvisor/pkg/hostarch"
@@ -57,9 +58,9 @@ type vdsoParams struct {
//
// +stateify savable
type VDSOParamPage struct {
// The parameter page is fr, allocated from mfp.MemoryFile().
mfp pgalloc.MemoryFileProvider
fr memmap.FileRange
// The parameter page is fr, allocated from mf.
mf *pgalloc.MemoryFile `state:"nosave"`
fr memmap.FileRange
// seq is the current sequence count written to the page.
//
@@ -78,17 +79,22 @@ type VDSOParamPage struct {
copyScratchBuffer []byte
}
// afterLoad is invoked by stateify.
func (v *VDSOParamPage) afterLoad(ctx context.Context) {
v.mf = pgalloc.MemoryFileFromContext(ctx)
}
// NewVDSOParamPage returns a VDSOParamPage.
//
// Preconditions:
// - fr is a single page allocated from mfp.MemoryFile(). VDSOParamPage does
// not take ownership of fr; it must remain allocated for the lifetime of the
// - fr is a single page allocated from mf. VDSOParamPage does not take
// ownership of fr; it must remain allocated for the lifetime of the
// VDSOParamPage.
// - VDSOParamPage must be the only writer to fr.
// - mfp.MemoryFile().MapInternal(fr) must return a single safemem.Block.
func NewVDSOParamPage(mfp pgalloc.MemoryFileProvider, fr memmap.FileRange) *VDSOParamPage {
// - mf.MapInternal(fr) must return a single safemem.Block.
func NewVDSOParamPage(mf *pgalloc.MemoryFile, fr memmap.FileRange) *VDSOParamPage {
return &VDSOParamPage{
mfp: mfp,
mf: mf,
fr: fr,
copyScratchBuffer: make([]byte, (*vdsoParams)(nil).SizeBytes()),
}
@@ -96,7 +102,7 @@ func NewVDSOParamPage(mfp pgalloc.MemoryFileProvider, fr memmap.FileRange) *VDSO
// access returns a mapping of the param page.
func (v *VDSOParamPage) access() (safemem.Block, error) {
bs, err := v.mfp.MemoryFile().MapInternal(v.fr, hostarch.ReadWrite)
bs, err := v.mf.MapInternal(v.fr, hostarch.ReadWrite)
if err != nil {
return safemem.Block{}, err
}
+3 -4
View File
@@ -179,7 +179,7 @@ type VDSO struct {
// PrepareVDSO validates the system VDSO and returns a VDSO, containing the
// param page for updating by the kernel.
func PrepareVDSO(mfp pgalloc.MemoryFileProvider) (*VDSO, error) {
func PrepareVDSO(mf *pgalloc.MemoryFile) (*VDSO, error) {
vdsoFile := &byteFullReader{data: vdsodata.Binary}
// First make sure the VDSO is valid. vdsoFile does not use ctx, so a
@@ -195,7 +195,6 @@ func PrepareVDSO(mfp pgalloc.MemoryFileProvider) (*VDSO, error) {
return nil, fmt.Errorf("VDSO size overflows? %#x", len(vdsodata.Binary))
}
mf := mfp.MemoryFile()
vdso, err := mf.Allocate(uint64(size), pgalloc.AllocOpts{Kind: usage.System})
if err != nil {
return nil, fmt.Errorf("unable to allocate VDSO memory: %v", err)
@@ -221,11 +220,11 @@ func PrepareVDSO(mfp pgalloc.MemoryFileProvider) (*VDSO, error) {
}
return &VDSO{
ParamPage: mm.NewSpecialMappable("[vvar]", mfp, paramPage),
ParamPage: mm.NewSpecialMappable("[vvar]", mf, paramPage),
// TODO(gvisor.dev/issue/157): Don't advertise the VDSO, as
// some applications may not be able to handle multiple [vdso]
// hints.
vdso: mm.NewSpecialMappable("", mfp, vdso),
vdso: mm.NewSpecialMappable("", mf, vdso),
os: info.os,
arch: info.arch,
phdrs: info.phdrs,
+8 -8
View File
@@ -246,18 +246,18 @@ func (aio *AIOContext) Drain() {
type aioMappable struct {
aioMappableRefs
mfp pgalloc.MemoryFileProvider
fr memmap.FileRange
mf *pgalloc.MemoryFile `state:"nosave"`
fr memmap.FileRange
}
var aioRingBufferSize = uint64(hostarch.Addr(linux.AIORingSize).MustRoundUp())
func newAIOMappable(ctx context.Context, mfp pgalloc.MemoryFileProvider) (*aioMappable, error) {
fr, err := mfp.MemoryFile().Allocate(aioRingBufferSize, pgalloc.AllocOpts{Kind: usage.Anonymous, MemCgID: pgalloc.MemoryCgroupIDFromContext(ctx)})
func newAIOMappable(ctx context.Context, mf *pgalloc.MemoryFile) (*aioMappable, error) {
fr, err := mf.Allocate(aioRingBufferSize, pgalloc.AllocOpts{Kind: usage.Anonymous, MemCgID: pgalloc.MemoryCgroupIDFromContext(ctx)})
if err != nil {
return nil, err
}
m := aioMappable{mfp: mfp, fr: fr}
m := aioMappable{mf: mf, fr: fr}
m.InitRefs()
return &m, nil
}
@@ -265,7 +265,7 @@ func newAIOMappable(ctx context.Context, mfp pgalloc.MemoryFileProvider) (*aioMa
// DecRef implements refs.RefCounter.DecRef.
func (m *aioMappable) DecRef(ctx context.Context) {
m.aioMappableRefs.DecRef(func() {
m.mfp.MemoryFile().DecRef(m.fr)
m.mf.DecRef(m.fr)
})
}
@@ -346,7 +346,7 @@ func (m *aioMappable) Translate(ctx context.Context, required, optional memmap.M
return []memmap.Translation{
{
Source: source,
File: m.mfp.MemoryFile(),
File: m.mf,
Offset: m.fr.Start + source.Start,
Perms: hostarch.AnyAccess,
},
@@ -368,7 +368,7 @@ func (mm *MemoryManager) NewAIOContext(ctx context.Context, events uint32) (uint
// libaio peeks inside looking for a magic number. This function allocates
// a page per context and keeps it set to zeroes to ensure it will not
// match AIO_RING_MAGIC and make libaio happy.
m, err := newAIOMappable(ctx, mm.mfp)
m, err := newAIOMappable(ctx, mm.mf)
if err != nil {
return 0, err
}
+10 -1
View File
@@ -14,9 +14,18 @@
package mm
import "context"
import (
"context"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
)
// afterLoad is invoked by stateify.
func (aio *AIOContext) afterLoad(context.Context) {
aio.requestReady = make(chan struct{}, 1)
}
// afterLoad is invoked by stateify.
func (m *aioMappable) afterLoad(ctx context.Context) {
m.mf = pgalloc.MemoryFileFromContext(ctx)
}

Some files were not shown because too many files have changed in this diff Show More