New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runtime: sysMemStat overflow on openbsd-mips64-jsing #52682
Comments
(CC @golang/openbsd, @golang/mips) |
Bisect shows https://go-review.googlesource.com/c/go/+/399474 is the bad commit |
The overflow is real: the scavenger tries to subtract 16 KiB from Looking at this, it either doesn't seem possible, or something horribly wrong is happening.
What could be happening is an allocation comes in and concurrently grabs those pages with the scavenger, decreasing What changed in https://go-review.googlesource.com/c/go/+/399474 is that there's a lock-free way of determining which 4 MiB chunks of memory have free pages. The thing is, that index is only updated with the lock held. And even if the scavenger notices that there could be pages in some 4 MiB chunk, it again always grabs the lock to check for certain and acquire those pages before doing anything. |
I will note that the other mips64 builders appear to be fine, at least when it comes to this issue. I have no idea how being on OpenBSD specifically causes this to happen. |
I've reassigned this to @4a6f656c. I don't have the time at this moment to look into this, and it's low priority for me because it's a second class port. I'm willing to take a look later, but I can't make any promises on when. |
This happens in schedinit, before gcinit, so the gcController hasn't been initialized. The bad value is -16384 (which equals to n=-16384), so the original value is indeed 0, i.e. uninitialized. The allocation is allocating the gsignal stack for m0. On all other platforms but OpenBSD/MIPS64, that stack size is 32K. But it is 64K on OpenBSD/MIPS64 https://cs.opensource.google/go/go/+/master:src/runtime/os_openbsd.go;l=157 Would it be possible to initialize the gcController earlier? Or we could allocate that particular stack in some special way (maybe |
Oh, huh. Thanks for digging into this. I think we should just initialize the gcController earlier. I suspect there are other (minor) issues with how late it's initialized. For instance, that means the memory limit is initialized pretty late. I think this will fix the problem because then But on another note, how can it find anything to scavenge at all? On other platforms, I believe that nothing is found at all. But if something is found, that suggests that |
This code https://cs.opensource.google/go/go/+/master:src/runtime/mheap.go;l=1185 calls That |
Oh, wow. OK. Thanks for figuring that out!! Ugh. This case is super annoying. When that memory gets allocated, its scavenged bits get cleared. So, when the edges of the allocation are subsequently freed, they're always considered unscavenged, even though we didn't actually use them. If we want to maintain that behavior, we need to figure out exactly how much of those "edge" pages were scavenged and make the appropriate update. This looks like it was pretty much always wrong; we just got lucky. We can avoid this entirely by just finding a big enough region that we can slice up, and then allocate only the aligned part in the first place, so we don't have to free the edges. I'll send a patch. |
Change https://go.dev/cl/407502 mentions this issue: |
Another, potentially simpler solution, would be to just always overallocate and have the stack code do the alignment. It wastes memory instead of CPU time, though. |
Example failure: https://build.golang.org/log/94e9c9c820d29aa509ffe49c14cb5c8784954f99
This started happening as of the SetMemoryLimit CLs. Notably, linux-mips64le looks OK.
The text was updated successfully, but these errors were encountered: