Skip to content
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

code runs as expected but kernel shows "no enough memory for the allocation" #4151

Open
laurento opened this issue Feb 25, 2024 · 3 comments
Labels

Comments

@laurento
Copy link

laurento commented Feb 25, 2024

I compiled my small tool using tinygo because I'm targeting a Raspberry Pi first generation with 256MB of RAM, so every byte counts :) It works just fine. However I just noticed that it generates the following kernel error every time it runs.

[33719.335172] __vm_enough_memory: pid: 7816, comm: mystuff, no enough memory for the allocation

If I compile it using GOOS=linux GOARCH=arm GOARM=6 tinygo build mystuff.go. If I run the same code but compiled it using go the kernel doesn't seem to complain.

For my tests I'm using:

Linux raspi 6.1.0-17-rpi #1 Debian 6.1.69-1 (2023-12-30) armv6l GNU/Linux
tinygo version 0.30.0 linux/amd64 (using go version go1.21.7 and LLVM version 16.0.1)
@peritonow
Copy link

peritonow commented Apr 26, 2024

I am new to tinygo as well, but there is no much to go on with the information you provided.

From my understanding this go code is translate to c and recompiled with "gcc" ...
https://forum.arduino.cc/t/not-enough-memory-coding-troubleshooting/417437 and the error is from c compiler.

so this might be a bug withing c library and nothing to do with tinygo... also might be related to go stack escape that embedded programming might not tolerate and you need to find out the problem lines within your go code. Hard to say.

last time over 30 yrs ago I was doing embedded in c ... program running just fine on linux would not work in embedded since hardware or embedded library coded for the specific chip set would not allow to exceed physical hardware limitation that library was coded for.

@aykevl
Copy link
Member

aykevl commented Apr 27, 2024

It's probably this code:

// Allocate a large chunk of virtual memory. Because it is virtual, it won't
// really be allocated in RAM. Memory will only be allocated when it is
// first touched.
heapMaxSize = 1 * 1024 * 1024 * 1024 // 1GB for the entire heap
for {
addr := mmap(nil, heapMaxSize, flag_PROT_READ|flag_PROT_WRITE, flag_MAP_PRIVATE|flag_MAP_ANONYMOUS, -1, 0)
if addr == unsafe.Pointer(^uintptr(0)) {
// Heap was too big to be mapped by mmap. Reduce the maximum size.
// We might want to make this a bit smarter than simply halving the
// heap size.
// This can happen on 32-bit systems.
heapMaxSize /= 2
continue
}
heapStart = uintptr(addr)
heapEnd = heapStart + heapSize
break
}

I'm surprised it prints a warning. Maybe the kernel really doesn't like an 1GB allocation? (It should just return an error if it is too big).

From my understanding this go code is translate to c and recompiled with "gcc" ...
https://forum.arduino.cc/t/not-enough-memory-coding-troubleshooting/417437 and the error is from c compiler.

It is not, we use LLVM as a compiler toolchain (and don't use GCC anywhere in the process).

@laurento
Copy link
Author

laurento commented Apr 27, 2024

Perhaps this kernel patch is relevant https://lore.kernel.org/linux-mm/18dc0807-5596-3aad-350d-3673a033bca8@redhat.com/T/

Edit: This thread too https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1031520

To my understanding, if brk triggers a 'no enough memory for the allocation'
condition, it should simply return an error code to the user space
process, and not generate any kernel level difficulties. brk just
reserves the memory, and does not actually allocate it until it is
written, so no oom machinery should be involved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants