Skip to content

Commit 55ec518

Browse files
committed
runtime: remove scavAddr in favor of address ranges
This change removes the concept of s.scavAddr in favor of explicitly reserving and unreserving address ranges. s.scavAddr has several problems with raciness that can cause the scavenger to miss updates, or move it back unnecessarily, forcing future scavenge calls to iterate over searched address space unnecessarily. This change achieves this by replacing scavAddr with a second addrRanges which is cloned from s.inUse at the end of each sweep phase. Ranges from this second addrRanges are then reserved by scavengers (with the reservation size proportional to the heap size) who are then able to safely iterate over those ranges without worry of another scavenger coming in. Fixes #35788. Change-Id: Ief01ae170384174875118742f6c26b2a41cbb66d Reviewed-on: https://go-review.googlesource.com/c/go/+/208378 Run-TryBot: Michael Knyszek <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: David Chase <[email protected]> Reviewed-by: Austin Clements <[email protected]>
1 parent b1a48af commit 55ec518

File tree

8 files changed

+305
-171
lines changed

8 files changed

+305
-171
lines changed

src/runtime/export_test.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -735,9 +735,12 @@ func (p *PageAlloc) Free(base, npages uintptr) {
735735
func (p *PageAlloc) Bounds() (ChunkIdx, ChunkIdx) {
736736
return ChunkIdx((*pageAlloc)(p).start), ChunkIdx((*pageAlloc)(p).end)
737737
}
738-
func (p *PageAlloc) Scavenge(nbytes uintptr, locked bool) (r uintptr) {
738+
func (p *PageAlloc) Scavenge(nbytes uintptr, mayUnlock bool) (r uintptr) {
739+
pp := (*pageAlloc)(p)
739740
systemstack(func() {
740-
r = (*pageAlloc)(p).scavenge(nbytes, locked)
741+
lock(pp.mheapLock)
742+
r = pp.scavenge(nbytes, mayUnlock)
743+
unlock(pp.mheapLock)
741744
})
742745
return
743746
}
@@ -819,7 +822,6 @@ func NewPageAlloc(chunks, scav map[ChunkIdx][]BitRange) *PageAlloc {
819822
}
820823
}
821824
}
822-
p.resetScavengeAddr()
823825

824826
// Apply alloc state.
825827
for _, s := range init {
@@ -833,6 +835,11 @@ func NewPageAlloc(chunks, scav map[ChunkIdx][]BitRange) *PageAlloc {
833835
// Update heap metadata for the allocRange calls above.
834836
p.update(addr, pallocChunkPages, false, false)
835837
}
838+
systemstack(func() {
839+
lock(p.mheapLock)
840+
p.scavengeStartGen()
841+
unlock(p.mheapLock)
842+
})
836843
return (*PageAlloc)(p)
837844
}
838845

src/runtime/extern.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,11 @@ It is a comma-separated list of name=val pairs setting these named variables:
104104
scavenger as well as the total amount of memory returned to the operating system
105105
and an estimate of physical memory utilization. The format of this line is subject
106106
to change, but currently it is:
107-
scav # KiB work, # KiB total, #% util
107+
scav # # KiB work, # KiB total, #% util
108108
where the fields are as follows:
109-
# KiB work the amount of memory returned to the OS since the last scav line
110-
# KiB total how much of the heap at this point in time has been released to the OS
109+
scav # the scavenge cycle number
110+
# KiB work the amount of memory returned to the OS since the last line
111+
# KiB total the total amount of memory returned to the OS
111112
#% util the fraction of all unscavenged memory which is in-use
112113
If the line ends with "(forced)", then scavenging was forced by a
113114
debug.FreeOSMemory() call.

0 commit comments

Comments
 (0)