Summary: | ocamlc fails trying to allocate 34 GB of RAM | ||||||
---|---|---|---|---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Radzevich Belevich <serp> | ||||
Component: | ocaml | Assignee: | Richard W.M. Jones <rjones> | ||||
Status: | CLOSED CURRENTRELEASE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> | ||||
Severity: | high | Docs Contact: | |||||
Priority: | low | ||||||
Version: | 8 | CC: | rjones | ||||
Target Milestone: | --- | Keywords: | Reopened | ||||
Target Release: | --- | ||||||
Hardware: | athlon | ||||||
OS: | Linux | ||||||
Whiteboard: | |||||||
Fixed In Version: | ocaml-3.10.1-3.fc9 | Doc Type: | Bug Fix | ||||
Doc Text: | Story Points: | --- | |||||
Clone Of: | |||||||
: | 877128 (view as bug list) | Environment: | |||||
Last Closed: | 2008-07-13 20:32:13 UTC | Type: | --- | ||||
Regression: | --- | Mount Type: | --- | ||||
Documentation: | --- | CRM: | |||||
Verified Versions: | Category: | --- | |||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
Cloudforms Team: | --- | Target Upstream Version: | |||||
Bug Depends On: | |||||||
Bug Blocks: | 438486, 441685, 454384 | ||||||
Attachments: |
|
Description
Radzevich Belevich
2008-05-07 14:50:16 UTC
I've not seen this and I routinely compile OCaml modules & OCaml itself on x86-64. Can you give the precise versions of the Fedora ocaml packages you're using please. [serp@serp pp]$ cat /etc/redhat-release Fedora release 9 (Sulphur) [serp@serp pp]$ uname -a Linux serp.office.stork.ru 2.6.25-14.fc9.x86_64 #1 SMP Thu May 1 06:06:21 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux [serp@serp pp]$ rpm -qa ocaml* ocaml-pcre-5.13.0-2.fc9.x86_64 ocaml-findlib-devel-1.2.1-2.fc9.i386 ocaml-camlp4-3.10.1-2.fc9.x86_64 ocaml-findlib-1.2.1-2.fc9.x86_64 ocaml-3.10.1-2.fc9.x86_64 ocaml-camlp4-devel-3.10.1-2.fc9.x86_64 ocaml-runtime-3.10.1-2.fc9.x86_64 ocaml-extlib-1.5.1-2.fc9.x86_64 [serp@serp pp]$ cat log.ml open Camlp4.PreCast; open Syntax; value insert_mname_mline _loc f = <:expr<Log.$lid:f$ $str:Loc.file_name _loc$ $`int:Loc.start_line _loc$>>; EXTEND Gram GLOBAL: expr; expr: [ [ "Log"; "."; f = [ `LIDENT ("e"|"d"|"w" as f) -> f] -> insert_mname_mline _loc f ] ]; END; [serp@serp pp]$ /usr/bin/ocamlc.opt -c -I +camlp4 -pp camlp4rf log.ml -o log.cmo Fatal error: out of memory. [serp@serp pp]$ /usr/bin/ocamlc.opt -c -I +camlp4 -pp camlp4rf log.ml -o log.cmo Fatal error: exception Out_of_memory Raised at file "", line 0, characters 0-0 Called from file "arg.ml", line 211, characters 4-32 [serp@serp pp]$ /usr/bin/ocamlc.opt -c -I +camlp4 -pp camlp4rf log.ml -o log.cmo [serp@serp pp]$ First of all I can't reproduce this on either my i386 & x86-64 machines with our ocaml-3.10.1-2 package. They all compile log.ml with the command shown without any error. Also I don't quite understand the commands you show above. Do you mean that when you run the ocamlc.opt command three times, you get three different outputs? Or are you running this on different machines or modifying the input in some manner? Also, can you do: ulimit -a free -m Just need to check there are no artificial limits in your setup. Yes, I run this command three time in a row, and get three different outputs. Last it's compiled successfully :-) But three it's not a regularity. Sometime it's success immediately, but sometimes three or more. [serp@serp pp]$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 8191 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 1024 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [serp@serp pp]$ free -m total used free shared buffers cached Mem: 1004 929 74 0 47 407 -/+ buffers/cache: 474 529 Swap: 1919 0 1919 ============================================== On i386 mashine, all ok. On ocaml 3.11+dev12 on this mashine (compiled from source), all ok. But ocaml 3.10.2 compilation has this problem. Yes, you're right - I can reproduce this if I run the ocamlc.opt command often enough, and in fact I've seen this bug before. Bug 438486 ocaml-camomile doesn't build on ppc64 (even in Rawhide) It's almost exactly the same symtoms too: ocamlc.opt tries to allocate 34 GB [sic] of RAM and obviously fails. It does this non-deterministically. Example from the strace: mmap(NULL, 34289692672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) A bit of informal testing seems to indicate this is a Fedora-specific problem, in that it doesn't appear to occur on Debian. I've posted about this issue on caml-list. Thanks for the small reproducer. Hopefully someone on caml-list will have some more insight, if not I'll take a closer look over the next few days. Reassigning the BZ to me, I'm sure gemi won't mind :-) I've tracked down the problem and come up with two possible solutions. My reasoning is contained in this thread in more detail: http://caml.inria.fr/pub/ml-archives/caml-list/2008/05/f03aa82c55e7dfcfb409536a28fcdedd.en.html The problem is essentially that Fedora mmap returns high memory addresses and the way the OCaml runtime is constructed, this is unexpected. OCaml runtime tries to construct a linear page table, an array tracking which pages are contained in the OCaml heap and which are regular pages (eg. external mallocs). This method doesn't work when pages can be present at very high memory addresses (or at least, it would work if the page table could be extended to 34 GB, but it can't be!) There are two possible solutions: (1) Easy hack but x86-64 only: Pass the MAP_32BIT flag to mmap. This causes mmap to return memory addresses below 2 GB, and fixes the problem. However (a) this is only available on x86-64 (not, eg, ppc64 where we also have the problem). (b) This limits the OCaml runtime to quite a small maximum heap, probably 1 or 2 GB max. (2) Difficult: In OCaml 3.11, the linear page table stuff has been completely rewritten to use a hash table, to get around this problem. We could in theory backport this to OCaml 3.10, but honestly the patch is huge and changes large amounts of the runtime, and I have little confidence I could do this backport correctly. I guess there is a third possibility which is to find out why mmap in Fedora behaves so differently from mmap in, say, Debian. I'll post a patch for (1) in a moment once I've done a bit more testing. Created attachment 304848 [details]
ocaml-3.10.1-map32bit.patch
Patch to pass MAP_32BIT to mmap.
Confirmed that this fixes the original reported problem
on x86-64 / F-9.
See also 454384; a request for a backport of this fix to F8. Reopening, assigning to F-8. Ooops - didn't see that we also have bug 454384. Closing again - I'm going to fix that one now. |