MCPcopy
hub / github.com/google/gvisor / updateUsageLocked

Method updateUsageLocked

pkg/sentry/pgalloc/pgalloc.go:1605–1741  ·  view source on GitHub ↗

updateUsageLocked attempts to detect commitment of previously-uncommitted pages, and updates memory accounting to reflect newly-committed pages. Precondition: f.mu must be held; it may be unlocked and reacquired. +checklocks:f.mu

(memCgIDs map[uint32]struct{})

Source from the content-addressed store, hash-verified

1603// Precondition: f.mu must be held; it may be unlocked and reacquired.
1604// +checklocks:f.mu
1605func (f *MemoryFile) updateUsageLocked(memCgIDs map[uint32]struct{}) error {
1606 // Track if anything changed to elide the merge.
1607 changedAny := false
1608 defer func() {
1609 if changedAny {
1610 f.memAcct.MergeAll()
1611 }
1612 }()
1613
1614 // Reused mincore buffer.
1615 var buf []byte
1616
1617 maseg := f.memAcct.FirstSegment()
1618 unscannedStart := uint64(0)
1619 for maseg.Ok() {
1620 ma := maseg.ValuePtr()
1621 if ma.wasteOrReleasing {
1622 // Skip scanning of waste and releasing pages. This isn't
1623 // necessarily correct, since !knownCommitted may have become
1624 // committed after the last call to updateUsageLocked(), then
1625 // transitioned from used to waste. However, this is consistent
1626 // with legacy behavior.
1627 maseg = maseg.NextSegment()
1628 continue
1629 }
1630 if ma.knownCommitted {
1631 // Known-committed pages remain known-committed until they are
1632 // decommitted.
1633 maseg = maseg.NextSegment()
1634 continue
1635 }
1636
1637 // Scan the pages of the given memCgID only. This will avoid scanning
1638 // the whole memory file when the memory usage is required only for a
1639 // specific cgroup. The total memory usage of all cgroups can be
1640 // obtained when memCgIDs is nil.
1641 if memCgIDs != nil {
1642 if _, ok := memCgIDs[ma.memCgID]; !ok {
1643 maseg = maseg.NextSegment()
1644 continue
1645 }
1646 }
1647
1648 fr := maseg.Range()
1649 if fr.Start < unscannedStart {
1650 fr.Start = unscannedStart
1651 }
1652 var checkErr error
1653 f.forEachChunk(fr, func(chunk *chunkInfo, chunkFR memmap.FileRange) bool {
1654 s := chunk.sliceAt(chunkFR)
1655
1656 // Ensure that we have sufficient buffer for the call (one byte per
1657 // page). The length of s must be page-aligned.
1658 bufLen := len(s) / hostarch.PageSize
1659 if len(buf) < bufLen {
1660 buf = make([]byte, bufLen)
1661 }
1662

Callers 1

UpdateUsageMethod · 0.95

Calls 15

forEachChunkMethod · 0.95
mincoreFunction · 0.85
MergeAllMethod · 0.80
FirstSegmentMethod · 0.80
ValuePtrMethod · 0.80
sliceAtMethod · 0.80
LowerBoundSegmentMethod · 0.80
IsolateMethod · 0.80
IncMethod · 0.80
UnlockMethod · 0.65
LockMethod · 0.65
StartMethod · 0.65

Tested by

no test coverage detected