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

Method DecRef

pkg/sentry/pgalloc/pgalloc.go:1201–1255  ·  view source on GitHub ↗

DecRef implements memmap.File.DecRef.

(fr memmap.FileRange)

Source from the content-addressed store, hash-verified

1199
1200// DecRef implements memmap.File.DecRef.
1201func (f *MemoryFile) DecRef(fr memmap.FileRange) {
1202 if !fr.WellFormed() || fr.Length() == 0 || !hostarch.IsPageAligned(fr.Start) || !hostarch.IsPageAligned(fr.End) {
1203 panic(fmt.Sprintf("invalid range: %v", fr))
1204 }
1205
1206 f.mu.Lock()
1207 defer f.mu.Unlock()
1208
1209 haveWaste := false
1210 f.forEachChunk(fr, func(chunk *chunkInfo, chunkFR memmap.FileRange) bool {
1211 unwaste := &f.unwasteSmall
1212 unfree := &f.unfreeSmall
1213 if chunk.huge {
1214 unwaste = &f.unwasteHuge
1215 unfree = &f.unfreeHuge
1216 }
1217 unfree.MutateFullRange(chunkFR, func(ufseg unfreeIterator) bool {
1218 uf := ufseg.ValuePtr()
1219 if uf.refs <= 0 {
1220 panic(fmt.Sprintf("DecRef(%v) called with %d references on pages %v", fr, uf.refs, ufseg.Range()))
1221 }
1222 uf.refs--
1223 if uf.refs == 0 {
1224 // Mark these pages as waste.
1225 wasteFR := ufseg.Range()
1226 unwaste.RemoveFullRange(wasteFR)
1227 haveWaste = true
1228 // Reclassify waste memory as System until it's recycled or
1229 // released.
1230 f.memAcct.MutateFullRange(wasteFR, func(maseg memAcctIterator) bool {
1231 ma := maseg.ValuePtr()
1232 if !f.opts.DisableMemoryAccounting && ma.knownCommitted {
1233 usage.MemoryAccounting.Move(maseg.Range().Length(), usage.System, ma.kind, ma.memCgID)
1234 }
1235 ma.kind = usage.System
1236 ma.wasteOrReleasing = true
1237 return true
1238 })
1239 // Cancel any pending async load on waste pages.
1240 if apl := f.asyncPageLoad.Load(); apl != nil {
1241 apl.cancelWasteLoad(wasteFR)
1242 }
1243 }
1244 return true
1245 })
1246 return true
1247 })
1248
1249 // Wake the releaser if we marked any pages as waste. Leave this until just
1250 // before unlocking f.mu.
1251 if haveWaste && !f.haveWaste {
1252 f.haveWaste = true
1253 f.releaseCond.Signal()
1254 }
1255}
1256
1257// releaserMain implements the releaser goroutine.
1258func (f *MemoryFile) releaserMain() {

Callers 1

AllocateMethod · 0.95

Calls 14

forEachChunkMethod · 0.95
IsPageAlignedFunction · 0.92
WellFormedMethod · 0.80
MutateFullRangeMethod · 0.80
ValuePtrMethod · 0.80
RemoveFullRangeMethod · 0.80
MoveMethod · 0.80
cancelWasteLoadMethod · 0.80
LockMethod · 0.65
UnlockMethod · 0.65
LoadMethod · 0.65
LengthMethod · 0.45

Tested by

no test coverage detected