From 287d1ec96c1271de532c6b1160cd9cbbe717ee34 Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Wed, 22 Apr 2020 21:36:11 +0000 Subject: runtime: ensure allocToCache updates searchAddr in a valid way Currently allocToCache assumes it can move the search address past the block it allocated the cache from, which violates the property that searchAddr should always point to mapped memory (i.e. memory represented by pageAlloc.inUse). This bug was already fixed once for pageAlloc.alloc in the Go 1.14 release via CL 216697, but that changed failed to take into account allocToCache. Fixes #38605. Change-Id: Id08180aa10d19dc0f9f551a1d9e327a295560dff Reviewed-on: https://go-review.googlesource.com/c/go/+/229577 Run-TryBot: Michael Knyszek TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- src/runtime/mpagecache_test.go | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'src/runtime/mpagecache_test.go') diff --git a/src/runtime/mpagecache_test.go b/src/runtime/mpagecache_test.go index b8cc0bd965..2ed0c0aa6a 100644 --- a/src/runtime/mpagecache_test.go +++ b/src/runtime/mpagecache_test.go @@ -260,12 +260,13 @@ func TestPageAllocAllocToCache(t *testing.T) { if GOOS == "openbsd" && testing.Short() { t.Skip("skipping because virtual memory is limited; see #36210") } - tests := map[string]struct { + type test struct { before map[ChunkIdx][]BitRange scav map[ChunkIdx][]BitRange hits []PageCache // expected base addresses and patterns after map[ChunkIdx][]BitRange - }{ + } + tests := map[string]test{ "AllFree": { before: map[ChunkIdx][]BitRange{ BaseChunkIdx: {}, @@ -349,6 +350,34 @@ func TestPageAllocAllocToCache(t *testing.T) { }, }, } + if PageAlloc64Bit != 0 { + const chunkIdxBigJump = 0x100000 // chunk index offset which translates to O(TiB) + + // This test is similar to the one with the same name for + // pageAlloc.alloc and serves the same purpose. + // See mpagealloc_test.go for details. + sumsPerPhysPage := ChunkIdx(PhysPageSize / PallocSumBytes) + baseChunkIdx := BaseChunkIdx &^ (sumsPerPhysPage - 1) + tests["DiscontiguousMappedSumBoundary"] = test{ + before: map[ChunkIdx][]BitRange{ + baseChunkIdx + sumsPerPhysPage - 1: {{0, PallocChunkPages - 1}}, + baseChunkIdx + chunkIdxBigJump: {{1, PallocChunkPages - 1}}, + }, + scav: map[ChunkIdx][]BitRange{ + baseChunkIdx + sumsPerPhysPage - 1: {}, + baseChunkIdx + chunkIdxBigJump: {}, + }, + hits: []PageCache{ + NewPageCache(PageBase(baseChunkIdx+sumsPerPhysPage-1, PallocChunkPages-64), 1<<63, 0), + NewPageCache(PageBase(baseChunkIdx+chunkIdxBigJump, 0), 1, 0), + NewPageCache(0, 0, 0), + }, + after: map[ChunkIdx][]BitRange{ + baseChunkIdx + sumsPerPhysPage - 1: {{0, PallocChunkPages}}, + baseChunkIdx + chunkIdxBigJump: {{0, PallocChunkPages}}, + }, + } + } for name, v := range tests { v := v t.Run(name, func(t *testing.T) { -- cgit v1.3