-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: cmd/go: build option to set env variable defaults #40870
Comments
I would like to add that priorities for options setters should be: |
If users are asking for this, it means we have failed at the way we configure programs. On top of that, program configuration belongs in programs not on build command lines. If the problem is bugs that can be disabled with GODEBUG settings, /cc @aclements |
In my case, I need to set values for "asyncpreemptoff" and "madvdontneed" for specific builds, no difference, is it "set on build" or "set by code". As a develop, I want to be sure program runs the way I plan it, giving users ability to override that with environment settings. |
These are called |
@aclements In my case I have build targets for linux hardware, running on kernel 3.14, and without madvdontneed it acts differently. I would accept any way, build options or runtime/debug calls. |
Sorry, but that doesn't really answer my question. Why do you need these options? How does it behave differently and why is it important that you change that? |
@networkimprov, lucky for us this build option wouldn't be backported either, so it isn't any better than a general fix to the EINTR problem. Let's solve that instead. |
It sounds like the real problem is that there are two runtime bugs that have not been adequately addressed, and too many people are working around them by setting GODEBUG settings. The two workarounds that are being overused are madvdontneed=1, for various perceived or actual out-of-memory conditions on Linux; and asyncpreemptoff=1, for various problems with spurious EINTR returns from Linux. For madvdontneed=1, I believe the state of the world is as @aclements summarized in #33376 (comment). Go is doing the same thing as Java and Node here. It should not be necessary to set that. It is unfortunate that Linux tools like top/htop do not subtract out the lazyfree total from RSS in the display, but the OS knows what it can take away and will do that rather than OOM. That comment also says that container memory limits understand what Go is doing here too, so this should not be causing container OOMs either. If someone is seeing problems here, we need to get more information about their exact setup to help understand it better. Hence the (unanswered) questions to @elgatito above and more importantly on #37569. If there are other cases where using MADV_FREE is causing OOMs, please file details in a different issue and we will try to get to the bottom of that. For asyncpreemptoff=1, the problem is that preemption has caused some (arguably buggy) kernel behavior returning EINTR where we weren't checking for it. And now I believe we are checking. If there are more places to check, let's fix those. In both cases, fixing the specific bugs is more effective and will be easier than adding a new build option we will have to support for all time. Let's fix the real bugs. |
Certainly fix the bugs, but why discount the value of letting end-users run apps with a preset GODEBUG (or other env) value? Why not a runtime/debug API for it? That is the only way you can possibly get debug info from certain sites. |
It's just more API surface that we are stuck with forever, and it's API surface that shouldn't even exist. |
Based on the discussion above, this seems like a likely decline. |
You just got another inquiry about this: #41818 (comment) |
@rsc I understand, you want to stay clear and avoid having environment variables hell, but, again, with the change of MADV_FREE behavior in Go, when running on hosts with old kernels (like 3.17) we get OOM from time to time. |
I think, each env variable should have method with its own documentation, instead of comment block in env variables. Because how madvdontneed=1 and production related to word goDEBUG? Also, I think, that defaults should be reviewed and who really needs performance ought to have ability to tune it. |
@elgatito, the answer for MADV_FREE is being discussed in #37569. It may be that we should just stop trying to use it, at least on Android, but possibly everywhere. That's separate from this discussion. @blinkinglight, these are meant to be temporary knobs, not permanent API. If lots of people need one, we're doing something wrong and we should fix it, as I commented above. |
No change in consensus, so declined. |
A workaround on unix might be to check
|
For what it's worth, It would be nice to have a way to choose between perception vs optimisation in cases like this that don't require setting environment variables. Not to mention that, for things built using |
Change https://golang.org/cl/267100 mentions this issue: |
In Go 1.12, we changed the runtime to use MADV_FREE when available on Linux (falling back to MADV_DONTNEED) in CL 135395 to address issue #23687. While MADV_FREE is somewhat faster than MADV_DONTNEED, it doesn't affect many of the statistics that MADV_DONTNEED does until the memory is actually reclaimed under OS memory pressure. This generally leads to poor user experience, like confusing stats in top and other monitoring tools; and bad integration with management systems that respond to memory usage. We've seen numerous issues about this user experience, including #41818, #39295, #37585, #33376, and #30904, many questions on Go mailing lists, and requests for mechanisms to change this behavior at run-time, such as #40870. There are also issues that may be a result of this, but root-causing it can be difficult, such as #41444 and #39174. And there's some evidence it may even be incompatible with Android's process management in #37569. This CL changes the default to prefer MADV_DONTNEED over MADV_FREE, to favor user-friendliness and minimal surprise over performance. I think it's become clear that Linux's implementation of MADV_FREE ultimately doesn't meet our needs. We've also made many improvements to the scavenger since Go 1.12. In particular, it is now far more prompt and it is self-paced, so it will simply trickle memory back to the system a little more slowly with this change. This can still be overridden by setting GODEBUG=madvdontneed=0. Fixes #42330 (meta-issue). Fixes #41818, #39295, #37585, #33376, #30904 (many of which were already closed as "working as intended"). Change-Id: Ib6aa7f2dc8419b32516cc5a5fc402faf576c92e4 Reviewed-on: https://go-review.googlesource.com/c/go/+/267100 Trust: Austin Clements <austin@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
@aclements @rsc @ianlancetaylor Here is another case #41099 (comment) describing the need to disable async preemption for all instances of an application (it trips up a required third-party library). In that light it may be worth reconsidering this proposal... |
Users are asking for a way to hard-code runtime environment variables, because their end-users cannot set them on app invocation.
I suggest a go build/test/run command-line option. Its use needn't be restricted to Go-specific variables. Existence of a variable in the environment at runtime would override any build-time default.
#37569 (comment) @elgatito
#40722 (comment) @gwillem
I considered a new stdlib API, but that opens the possibility of conflict between packages. A way to prevent that is to restrict the API to package
main
, but that seems unprecedented.EDIT: fix example to use semicolon delimiter
The text was updated successfully, but these errors were encountered: