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

Method releaseLocked

pkg/sentry/pgalloc/pgalloc.go:1309–1431  ·  view source on GitHub ↗

Preconditions: f.mu must be locked; it may be unlocked and reacquired.

(fr memmap.FileRange, huge bool)

Source from the content-addressed store, hash-verified

1307
1308// Preconditions: f.mu must be locked; it may be unlocked and reacquired.
1309func (f *MemoryFile) releaseLocked(fr memmap.FileRange, huge bool) {
1310 defer func() {
1311 maseg := f.memAcct.LowerBoundSegmentSplitBefore(fr.Start)
1312 for maseg.Ok() && maseg.Start() < fr.End {
1313 maseg = f.memAcct.SplitAfter(maseg, fr.End)
1314 ma := maseg.ValuePtr()
1315 if ma.kind != usage.System {
1316 panic(fmt.Sprintf("waste pages %v have unexpected kind %v\n%s", maseg.Range(), ma.kind, f.stringLocked()))
1317 }
1318 if ma.knownCommitted {
1319 malen := maseg.Range().Length()
1320 f.knownCommittedBytes -= malen
1321 if !f.opts.DisableMemoryAccounting {
1322 usage.MemoryAccounting.Dec(malen, ma.kind, ma.memCgID)
1323 }
1324 }
1325 maseg = f.memAcct.Remove(maseg).NextSegment()
1326 }
1327 }()
1328
1329 if !huge {
1330 // Decommit the range being released, then mark the released range as
1331 // freed.
1332 f.mu.Unlock()
1333 f.decommitOrManuallyZero(fr)
1334 f.mu.Lock()
1335 f.unfreeSmall.RemoveFullRange(fr)
1336 return
1337 }
1338
1339 // Handle huge pages and sub-release.
1340
1341 firstHugeStart := hostarch.HugePageRoundDown(fr.Start)
1342 lastHugeStart := hostarch.HugePageRoundDown(fr.End - 1)
1343 firstHugeEnd := firstHugeStart + hostarch.HugePageSize
1344 lastHugeEnd := lastHugeStart + hostarch.HugePageSize
1345 if firstHugeStart == lastHugeStart {
1346 // All of fr falls within a single huge page.
1347 oldSubrel := f.subreleased[firstHugeStart]
1348 incSubrel := fr.Length() / hostarch.PageSize
1349 newSubrel := oldSubrel + incSubrel
1350 if newSubrel == pagesPerHugePage {
1351 // Free this huge page.
1352 //
1353 // When a small page within a hugepage-backed allocation is
1354 // individually deallocated (becomes waste), we decommit it to
1355 // reduce memory usage (and for consistency with legacy behavior).
1356 // This requires the host to split the containing huge page, if one
1357 // exists. khugepaged may later re-assemble the containing huge
1358 // page, implicitly re-committing previously-decommitted small
1359 // pages as a result.
1360 //
1361 // Thus: When a huge page is freed, ensure that the whole huge page
1362 // is decommitted rather than just the final small page(s), to
1363 // ensure that we leave behind an uncommitted hugepage-sized range
1364 // with no re-committed small pages.
1365 if oldSubrel != 0 {
1366 delete(f.subreleased, firstHugeStart)

Callers 1

releaserMainMethod · 0.95

Calls 15

stringLockedMethod · 0.95
HugePageRoundDownFunction · 0.92
deleteStruct · 0.85
SplitAfterMethod · 0.80
ValuePtrMethod · 0.80
DecMethod · 0.80
RemoveFullRangeMethod · 0.80
StartMethod · 0.65
UnlockMethod · 0.65
LockMethod · 0.65

Tested by

no test coverage detected