Bug 445545

Summary: ocamlc fails trying to allocate 34 GB of RAM
Product: [Fedora] Fedora Reporter: Radzevich Belevich <serp>
Component: ocamlAssignee: Richard W.M. Jones <rjones>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: high Docs Contact:
Priority: low    
Version: 8CC: rjones
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: athlon   
OS: Linux   
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    
Description Flags
ocaml-3.10.1-map32bit.patch none

Description Radzevich Belevich 2008-05-07 14:50:16 UTC
Description of problem: 

x84_84 arch

"ocamlc" could not compile my modules: Exception Out_of_memory

I'am could not compile ocaml 3.10.1 and 3.10.2 from source: 
  Exception Out_of_memory

From cvs HEAD ocaml 3.11d+dev12 compiled successfully.

Comment 1 Richard W.M. Jones 2008-05-07 15:00:13 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.

Comment 2 Radzevich Belevich 2008-05-07 15:53:38 UTC
[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*

[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$>>; 

  GLOBAL: expr;
        [ "Log"; "."; f = [ `LIDENT ("e"|"d"|"w" as f) -> f] ->
insert_mname_mline _loc f ]

[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]$ 

Comment 3 Richard W.M. Jones 2008-05-07 16:16:09 UTC
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?

Comment 4 Richard W.M. Jones 2008-05-07 16:20:28 UTC
Also, can you do:

ulimit -a
free -m

Just need to check there are no artificial limits in your setup.

Comment 5 Radzevich Belevich 2008-05-07 16:29:43 UTC
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.

Comment 6 Radzevich Belevich 2008-05-07 16:35:35 UTC
[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.

Comment 7 Richard W.M. Jones 2008-05-07 16:52:39 UTC
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

Example from the strace:

= -1 ENOMEM (Cannot allocate memory)

Comment 8 Richard W.M. Jones 2008-05-07 17:30:07 UTC
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 :-)

Comment 9 Richard W.M. Jones 2008-05-08 10:52:09 UTC
I've tracked down the problem and come up with two possible solutions.
My reasoning is contained in this thread in more detail:


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.

Comment 10 Richard W.M. Jones 2008-05-08 11:09:10 UTC
Created attachment 304848 [details]

Patch to pass MAP_32BIT to mmap.

Confirmed that this fixes the original reported problem
on x86-64 / F-9.

Comment 11 Stephen Warren 2008-07-10 16:54:07 UTC
See also 454384; a request for a backport of this fix to F8.

Comment 12 Richard W.M. Jones 2008-07-13 20:29:58 UTC
Reopening, assigning to F-8.

Comment 13 Richard W.M. Jones 2008-07-13 20:32:13 UTC
Ooops - didn't see that we also have bug 454384.  Closing again - I'm
going to fix that one now.