All of lore.kernel.org
 help / color / mirror / Atom feed
* strange stack limit behavior when allocating more than 2GB mem on  32bit machine
@ 2009-08-21  3:47 Joe
  2009-08-21  6:58 ` Glynn Clements
  2009-08-21  7:09 ` Michał Nazarewicz
  0 siblings, 2 replies; 10+ messages in thread
From: Joe @ 2009-08-21  3:47 UTC (permalink / raw)
  To: linux-c-programming

Hi,

Here I encounter something which I can't understand.
What I want to do is to allocate ~2.5GB mem, it fails when stack limit
is unlimited, but succeeded when stack limit is 10240.

Here is the code:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
        char *p;
        long i;
        size_t n;

        if (argc != 2 || atol(argv[1]) <= 0) {
                fprintf(stderr, "usage: malloc value (MB)\n");
                return 1;
        }
        n = 1024 * 1024 * atol(argv[1]);
        if (!(p = malloc(n))) {
                perror("malloc failed");
                return 2;
        }
        printf("Malloc succeeded\n");
        free(p);
        return 0;
}


and here is what confused me:

$ uname -a
Linux stone 2.6.9-11.ELsmp #1 SMP Fri May 20 18:26:27 EDT 2005 i686
i686 i386 GNU/Linux <==== 32bit system
$ free -m
             total       used       free     shared    buffers     cached
Mem:          2024       1996         28          0         30       1401
-/+ buffers/cache:        563       1461
Swap:        10236          0      10236
$ ulimit -s
10240
$ ./malloc 2500
Malloc succeeded               <======= succeeds when stack limit is 10240
$ ulimit -s unlimited
$ ./malloc 2500
malloc failed: Cannot allocate memory   <======== fails when stack
limit is unlimited???


BTW, there is no such problem on 64bit machine


Could you please give some insight on this?

Regards

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on  32bit machine
  2009-08-21  3:47 strange stack limit behavior when allocating more than 2GB mem on 32bit machine Joe
@ 2009-08-21  6:58 ` Glynn Clements
  2009-08-21  9:12   ` Joe
  2009-08-21  7:09 ` Michał Nazarewicz
  1 sibling, 1 reply; 10+ messages in thread
From: Glynn Clements @ 2009-08-21  6:58 UTC (permalink / raw)
  To: Joe; +Cc: linux-c-programming


Joe wrote:

> Here I encounter something which I can't understand.
> What I want to do is to allocate ~2.5GB mem, it fails when stack limit
> is unlimited, but succeeded when stack limit is 10240.

> $ ulimit -s
> 10240
> $ ./malloc 2500
> Malloc succeeded               <======= succeeds when stack limit is 10240
> $ ulimit -s unlimited
> $ ./malloc 2500
> malloc failed: Cannot allocate memory   <======== fails when stack
> limit is unlimited???
> 
> 
> BTW, there is no such problem on 64bit machine
> 
> 
> Could you please give some insight on this?

A 32-bit system has a 4 GiB address space. The top GiB is reserved for
the kernel. If you set a stack size of unlimited, 2 GiB are reserved
for the stack and shared libraries, causing shared libraries to be
mapped at 1GiB and up. This leaves around 860 MiB for the heap.

The result is that there isn't any areay of the address space which is
large enough for a single 2500 MiB allocation:

glynn@cerise:~ $ ulimit -s 8192
glynn@cerise:~ $ cat /proc/self/maps
08048000-08053000 r-xp 00000000 08:01 3966484    /bin/cat
08053000-08054000 r--p 0000a000 08:01 3966484    /bin/cat
08054000-08055000 rw-p 0000b000 08:01 3966484    /bin/cat
080a4000-080c6000 rw-p 080a4000 00:00 0          [heap]
b7f67000-b7f68000 rw-p b7f67000 00:00 0 
b7f68000-b80a0000 r-xp 00000000 08:01 9784624    /lib/libc-2.9.so
b80a0000-b80a2000 r--p 00138000 08:01 9784624    /lib/libc-2.9.so
b80a2000-b80a3000 rw-p 0013a000 08:01 9784624    /lib/libc-2.9.so
b80a3000-b80a6000 rw-p b80a3000 00:00 0 
b80bd000-b80be000 rw-p b80bd000 00:00 0 
b80be000-b80bf000 r-xp b80be000 00:00 0          [vdso]
b80bf000-b80db000 r-xp 00000000 08:01 9785919    /lib/ld-2.9.so
b80db000-b80dc000 r--p 0001b000 08:01 9785919    /lib/ld-2.9.so
b80dc000-b80dd000 rw-p 0001c000 08:01 9785919    /lib/ld-2.9.so
bf81e000-bf833000 rw-p bffeb000 00:00 0          [stack]

glynn@cerise:~ $ ulimit -s unlimited
glynn@cerise:~ $ cat /proc/self/maps 
08048000-08053000 r-xp 00000000 08:01 3966484    /bin/cat
08053000-08054000 r--p 0000a000 08:01 3966484    /bin/cat
08054000-08055000 rw-p 0000b000 08:01 3966484    /bin/cat
0a016000-0a038000 rw-p 0a016000 00:00 0          [heap]
40000000-4001c000 r-xp 00000000 08:01 9785919    /lib/ld-2.9.so
4001c000-4001d000 r--p 0001b000 08:01 9785919    /lib/ld-2.9.so
4001d000-4001e000 rw-p 0001c000 08:01 9785919    /lib/ld-2.9.so
4001e000-4001f000 r-xp 4001e000 00:00 0          [vdso]
4001f000-40020000 rw-p 4001f000 00:00 0 
40037000-4016f000 r-xp 00000000 08:01 9784624    /lib/libc-2.9.so
4016f000-40171000 r--p 00138000 08:01 9784624    /lib/libc-2.9.so
40171000-40172000 rw-p 0013a000 08:01 9784624    /lib/libc-2.9.so
40172000-40176000 rw-p 40172000 00:00 0 
bfb35000-bfb4a000 rw-p bffeb000 00:00 0          [stack]

If you were to allocate 1900 MiB, the allocation would succeed with
e.g. "ulimit -s 8192" (the allocation coming from the heap) or with
"ulimit -s unlimited" (the allocation coming from the stack), but
would fail with intermediate values, as neither region is large
enough.

-- 
Glynn Clements <glynn@gclements.plus.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on 32bit machine
  2009-08-21  3:47 strange stack limit behavior when allocating more than 2GB mem on 32bit machine Joe
  2009-08-21  6:58 ` Glynn Clements
@ 2009-08-21  7:09 ` Michał Nazarewicz
  1 sibling, 0 replies; 10+ messages in thread
From: Michał Nazarewicz @ 2009-08-21  7:09 UTC (permalink / raw)
  To: Joe, linux-c-programming

On Fri, 21 Aug 2009 05:47:28 +0200, Joe <longapple@gmail.com> wrote:

> Here I encounter something which I can't understand.
> What I want to do is to allocate ~2.5GB mem, it fails when stack limit
> is unlimited, but succeeded when stack limit is 10240.

I cannot really answer your question but maybe this will give
you some more insight:

> $ free -m
>              total       used       free     shared    buffers     cached
> Mem:          2024       1996         28          0         30       1401
> -/+ buffers/cache:        563       1461
> Swap:        10236          0      10236
> $ ulimit -s
> 10240
> $ ./malloc 2500
> Malloc succeeded               <======= succeeds when stack limit is 10240
> $ ulimit -s unlimited
> $ ./malloc 2500
> malloc failed: Cannot allocate memory   <======== fails when stack
> limit is unlimited???

On 32-bit system, in standard configuration, user space programs can address
up to 3GiB of RAM (the other 1GiB is reserved for kernel).  It's possible
that with unlimited stack Linux reserves more address space for stack leaving
less for heap -- this may cause malloc(3) to fail.

> BTW, there is no such problem on 64bit machine

On 64-bit system, the 3GiB address space limit described above does not exist
and thus, if I'm correct, the program will succeed.

BTW. By default Linux does not allocate memory when calling malloc(3)
(sbrk(2) in fact). The pages are allocated when they are first
referenced.  This means, that even though malloc(3) returns non-NULL you
may have no access to the allocated area -- ie. program will segfault
trying to access it.  Yes, this is in violation of the C standard.

-- 
Best regards,                                            _     _
  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
  ..o | Computer Science,  Micha³ "mina86" Nazarewicz      (o o)
  ooo +-----<mina86@tlen.pl>----<mina86@jabber.org>----ooO--(_)--Ooo--

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on  32bit machine
  2009-08-21  6:58 ` Glynn Clements
@ 2009-08-21  9:12   ` Joe
  2009-08-21  9:37     ` Nicholas Mc Guire
  2009-08-21  9:38     ` Michał Nazarewicz
  0 siblings, 2 replies; 10+ messages in thread
From: Joe @ 2009-08-21  9:12 UTC (permalink / raw)
  To: Glynn Clements; +Cc: linux-c-programming

Hi Glynn,

Thanks for your explanation. However as you can see, I got 2GB mem and
~10GB swap, totally 12GB.

With ulimit -s 10240(KB), I can allocate 2.5GB, I guess these are in
swap, right?
With ulimit -s unlimited, as you said, kernel reserved 1GB, stack
reserved 2GB, there are still 12-3=9GB left??

Why did malloc failed, instead of allocating this abundant swap space?

Regards,
Joe



On Thu, Aug 20, 2009 at 10:58 PM, Glynn
Clements<glynn@gclements.plus.com> wrote:
>
> Joe wrote:
>
>> Here I encounter something which I can't understand.
>> What I want to do is to allocate ~2.5GB mem, it fails when stack limit
>> is unlimited, but succeeded when stack limit is 10240.
>
>> $ ulimit -s
>> 10240
>> $ ./malloc 2500
>> Malloc succeeded               <======= succeeds when stack limit is 10240
>> $ ulimit -s unlimited
>> $ ./malloc 2500
>> malloc failed: Cannot allocate memory   <======== fails when stack
>> limit is unlimited???
>>
>>
>> BTW, there is no such problem on 64bit machine
>>
>>
>> Could you please give some insight on this?
>
> A 32-bit system has a 4 GiB address space. The top GiB is reserved for
> the kernel. If you set a stack size of unlimited, 2 GiB are reserved
> for the stack and shared libraries, causing shared libraries to be
> mapped at 1GiB and up. This leaves around 860 MiB for the heap.
>
> The result is that there isn't any areay of the address space which is
> large enough for a single 2500 MiB allocation:
>
> glynn@cerise:~ $ ulimit -s 8192
> glynn@cerise:~ $ cat /proc/self/maps
> 08048000-08053000 r-xp 00000000 08:01 3966484    /bin/cat
> 08053000-08054000 r--p 0000a000 08:01 3966484    /bin/cat
> 08054000-08055000 rw-p 0000b000 08:01 3966484    /bin/cat
> 080a4000-080c6000 rw-p 080a4000 00:00 0          [heap]
> b7f67000-b7f68000 rw-p b7f67000 00:00 0
> b7f68000-b80a0000 r-xp 00000000 08:01 9784624    /lib/libc-2.9.so
> b80a0000-b80a2000 r--p 00138000 08:01 9784624    /lib/libc-2.9.so
> b80a2000-b80a3000 rw-p 0013a000 08:01 9784624    /lib/libc-2.9.so
> b80a3000-b80a6000 rw-p b80a3000 00:00 0
> b80bd000-b80be000 rw-p b80bd000 00:00 0
> b80be000-b80bf000 r-xp b80be000 00:00 0          [vdso]
> b80bf000-b80db000 r-xp 00000000 08:01 9785919    /lib/ld-2.9.so
> b80db000-b80dc000 r--p 0001b000 08:01 9785919    /lib/ld-2.9.so
> b80dc000-b80dd000 rw-p 0001c000 08:01 9785919    /lib/ld-2.9.so
> bf81e000-bf833000 rw-p bffeb000 00:00 0          [stack]
>
> glynn@cerise:~ $ ulimit -s unlimited
> glynn@cerise:~ $ cat /proc/self/maps
> 08048000-08053000 r-xp 00000000 08:01 3966484    /bin/cat
> 08053000-08054000 r--p 0000a000 08:01 3966484    /bin/cat
> 08054000-08055000 rw-p 0000b000 08:01 3966484    /bin/cat
> 0a016000-0a038000 rw-p 0a016000 00:00 0          [heap]
> 40000000-4001c000 r-xp 00000000 08:01 9785919    /lib/ld-2.9.so
> 4001c000-4001d000 r--p 0001b000 08:01 9785919    /lib/ld-2.9.so
> 4001d000-4001e000 rw-p 0001c000 08:01 9785919    /lib/ld-2.9.so
> 4001e000-4001f000 r-xp 4001e000 00:00 0          [vdso]
> 4001f000-40020000 rw-p 4001f000 00:00 0
> 40037000-4016f000 r-xp 00000000 08:01 9784624    /lib/libc-2.9.so
> 4016f000-40171000 r--p 00138000 08:01 9784624    /lib/libc-2.9.so
> 40171000-40172000 rw-p 0013a000 08:01 9784624    /lib/libc-2.9.so
> 40172000-40176000 rw-p 40172000 00:00 0
> bfb35000-bfb4a000 rw-p bffeb000 00:00 0          [stack]
>
> If you were to allocate 1900 MiB, the allocation would succeed with
> e.g. "ulimit -s 8192" (the allocation coming from the heap) or with
> "ulimit -s unlimited" (the allocation coming from the stack), but
> would fail with intermediate values, as neither region is large
> enough.
>
> --
> Glynn Clements <glynn@gclements.plus.com>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on 32bit machine
  2009-08-21  9:12   ` Joe
@ 2009-08-21  9:37     ` Nicholas Mc Guire
  2009-08-21 10:33       ` Michał Nazarewicz
  2009-08-21  9:38     ` Michał Nazarewicz
  1 sibling, 1 reply; 10+ messages in thread
From: Nicholas Mc Guire @ 2009-08-21  9:37 UTC (permalink / raw)
  To: Joe; +Cc: Glynn Clements, linux-c-programming

On Fri, 21 Aug 2009, Joe wrote:

> Hi Glynn,
> 
> Thanks for your explanation. However as you can see, I got 2GB mem and
> ~10GB swap, totally 12GB.
> 
> With ulimit -s 10240(KB), I can allocate 2.5GB, I guess these are in
> swap, right?
> With ulimit -s unlimited, as you said, kernel reserved 1GB, stack
> reserved 2GB, there are still 12-3=9GB left??
> 
> Why did malloc failed, instead of allocating this abundant swap space?
>
initializing 12GB swap will not change the address space limit unless you
enabled high-memory support in the kernel (CONFIG_HIGHMEM64G=y in your .config)
the limit is not the physical memory (RAM+swap) but the 32bit address space.

hofrat

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on 32bit machine
  2009-08-21  9:12   ` Joe
  2009-08-21  9:37     ` Nicholas Mc Guire
@ 2009-08-21  9:38     ` Michał Nazarewicz
  2009-08-21 11:04       ` Joe
  1 sibling, 1 reply; 10+ messages in thread
From: Michał Nazarewicz @ 2009-08-21  9:38 UTC (permalink / raw)
  To: Joe, Glynn Clements; +Cc: linux-c-programming

On Fri, 21 Aug 2009 11:12:17 +0200, Joe wrote:
> Thanks for your explanation. However as you can see, I got 2GB mem and
> ~10GB swap, totally 12GB.
>
> With ulimit -s 10240(KB), I can allocate 2.5GB, I guess these are in
> swap, right?
> With ulimit -s unlimited, as you said, kernel reserved 1GB, stack
> reserved 2GB, there are still 12-3=9GB left??

Physical memory and swap are not the only limitations -- the other is
address space.  On 32-bit x86 systems CPU can address at most 4 GiB
of RAM[1].  Furthermore, in default configuration of Linux top 1 GiB
is reserved for kernel.  This means user space application can
address up to 3GiB of memory.

Now, as Glynn explained:

> On Thu, Aug 20, 2009 at 10:58 PM, Glynn Clements wrote:
>> If you set a stack size of unlimited, 2 GiB are reserved
>> for the stack and shared libraries, causing shared libraries to be
>> mapped at 1GiB and up. This leaves around 860 MiB for the heap.
>>
>> The result is that there isn't any area of the address space which is
>> large enough for a single 2500 MiB allocation:

> Why did malloc failed, instead of allocating this abundant swap space?

malloc(3) failed because it failed to allocate *address space* not memory.
In default configuration malloc(3) won't fail if there is not enough
memory anyways (try it yourself -- disable swap and try allocating
1.5 GiB).

As you can see on the memory map's Glenn provided:

>> glynn@cerise:~ $ cat /proc/self/maps
>> 08048000-08053000 r-xp 00000000 08:01 3966484    /bin/cat
>> 08053000-08054000 r--p 0000a000 08:01 3966484    /bin/cat
>> 08054000-08055000 rw-p 0000b000 08:01 3966484    /bin/cat
>> 0a016000-0a038000 rw-p 0a016000 00:00 0          [heap]
>> 40000000-4001c000 r-xp 00000000 08:01 9785919    /lib/ld-2.9.so
>> 4001c000-4001d000 r--p 0001b000 08:01 9785919    /lib/ld-2.9.so
>> 4001d000-4001e000 rw-p 0001c000 08:01 9785919    /lib/ld-2.9.so
>> 4001e000-4001f000 r-xp 4001e000 00:00 0          [vdso]
>> 4001f000-40020000 rw-p 4001f000 00:00 0
>> 40037000-4016f000 r-xp 00000000 08:01 9784624    /lib/libc-2.9.so
>> 4016f000-40171000 r--p 00138000 08:01 9784624    /lib/libc-2.9.so
>> 40171000-40172000 rw-p 0013a000 08:01 9784624    /lib/libc-2.9.so
>> 40172000-40176000 rw-p 40172000 00:00 0
>> bfb35000-bfb4a000 rw-p bffeb000 00:00 0          [stack]

there is no continuous block of 2 GiB virtual address space (this is
because Linux changes the location where libraries are mapped).  When
you request allocation of 2.5 GiB system has to find a large enough
hole between allocated regions and there isn't any.  See for
yourself and analyze the hexadecimal numbers on the left column

On 64-bit systems the problem does not occur because applications
use larger virtual address (48-bit if I'm not mistaken which is
256 TiB)


PS. Do not top-post.


[1] With Physical Address Extension[2] CPU can address more memory (64 GiB) but
     each application can address up to 4GiB anyways so lets ignore it for now.
[2] http://en.wikipedia.org/wiki/Physical_Address_Extension

-- 
Best regards,                                            _     _
  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
  ..o | Computer Science,  Micha³ "mina86" Nazarewicz      (o o)
  ooo +----<mina86@mina86.com>---<mina86@jabber.org>-ooO----(_)--Ooo--

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on 32bit machine
  2009-08-21  9:37     ` Nicholas Mc Guire
@ 2009-08-21 10:33       ` Michał Nazarewicz
  0 siblings, 0 replies; 10+ messages in thread
From: Michał Nazarewicz @ 2009-08-21 10:33 UTC (permalink / raw)
  To: Nicholas Mc Guire, Joe; +Cc: Glynn Clements, linux-c-programming

> On Fri, 21 Aug 2009, Joe wrote:
>> Thanks for your explanation. However as you can see, I got 2GB mem and
>> ~10GB swap, totally 12GB.
>>
>> With ulimit -s 10240(KB), I can allocate 2.5GB, I guess these are in
>> swap, right?
>> With ulimit -s unlimited, as you said, kernel reserved 1GB, stack
>> reserved 2GB, there are still 12-3=9GB left??
>>
>> Why did malloc failed, instead of allocating this abundant swap space?

On Fri, 21 Aug 2009 11:37:50 +0200, Nicholas Mc Guire <mcguire@lzu.edu.cn> wrote:
> Initializing 12GB swap will not change the address space limit unless you
> enabled high-memory support in the kernel (CONFIG_HIGHMEM64G=y in your .config)
> the limit is not the physical memory (RAM+swap) but the 32bit address space.

This won't help either since CONFIG_HIGHMEM64G (ie. Physical Address Extension)
affects only physical (not virtual) address space.  Because Joe has 1 GiB
HIGHMEM64G it will only slow his computer down (virtual->physical address
translation requires one more read when HIGHMEM64G is enabled).  Even with
gazillion GiBs of RAM CONFIG_HIGHMEM64G won't help here because the problem
is *virtual* address space limits which is 32-bit on 32-bit x86 systems
(regardless high memory (be it 4G or 64G) being enabled).

-- 
Best regards,                                            _     _
  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
  ..o | Computer Science,  Micha³ "mina86" Nazarewicz      (o o)
  ooo +----<mina86@mina86.com>---<mina86@jabber.org>-ooO----(_)--Ooo--

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on  32bit machine
  2009-08-21  9:38     ` Michał Nazarewicz
@ 2009-08-21 11:04       ` Joe
  2009-08-21 12:21         ` Michał Nazarewicz
  2009-08-22  7:44         ` Glynn Clements
  0 siblings, 2 replies; 10+ messages in thread
From: Joe @ 2009-08-21 11:04 UTC (permalink / raw)
  To: Michał Nazarewicz; +Cc: Glynn Clements, linux-c-programming

Clear. But how comes 2000MB can be allocated when stack limit is unlimited?

$ ulimit -s
unlimited
$ ./malloc 2046
Malloc succeeded
$ ./malloc 2047
malloc failed: Cannot allocate memory           <==== the critical
point for my case is 2046MB

Thanks,
Joe



2009/8/21 Micha³ Nazarewicz <m.nazarewicz@samsung.com>:
> On Fri, 21 Aug 2009 11:12:17 +0200, Joe wrote:
>>
>> Thanks for your explanation. However as you can see, I got 2GB mem and
>> ~10GB swap, totally 12GB.
>>
>> With ulimit -s 10240(KB), I can allocate 2.5GB, I guess these are in
>> swap, right?
>> With ulimit -s unlimited, as you said, kernel reserved 1GB, stack
>> reserved 2GB, there are still 12-3=9GB left??
>
> Physical memory and swap are not the only limitations -- the other is
> address space.  On 32-bit x86 systems CPU can address at most 4 GiB
> of RAM[1].  Furthermore, in default configuration of Linux top 1 GiB
> is reserved for kernel.  This means user space application can
> address up to 3GiB of memory.
>
> Now, as Glynn explained:
>
>> On Thu, Aug 20, 2009 at 10:58 PM, Glynn Clements wrote:
>>>
>>> If you set a stack size of unlimited, 2 GiB are reserved
>>> for the stack and shared libraries, causing shared libraries to be
>>> mapped at 1GiB and up. This leaves around 860 MiB for the heap.
>>>
>>> The result is that there isn't any area of the address space which is
>>> large enough for a single 2500 MiB allocation:
>
>> Why did malloc failed, instead of allocating this abundant swap space?
>
> malloc(3) failed because it failed to allocate *address space* not memory.
> In default configuration malloc(3) won't fail if there is not enough
> memory anyways (try it yourself -- disable swap and try allocating
> 1.5 GiB).
>
> As you can see on the memory map's Glenn provided:
>
>>> glynn@cerise:~ $ cat /proc/self/maps
>>> 08048000-08053000 r-xp 00000000 08:01 3966484    /bin/cat
>>> 08053000-08054000 r--p 0000a000 08:01 3966484    /bin/cat
>>> 08054000-08055000 rw-p 0000b000 08:01 3966484    /bin/cat
>>> 0a016000-0a038000 rw-p 0a016000 00:00 0          [heap]
>>> 40000000-4001c000 r-xp 00000000 08:01 9785919    /lib/ld-2.9.so
>>> 4001c000-4001d000 r--p 0001b000 08:01 9785919    /lib/ld-2.9.so
>>> 4001d000-4001e000 rw-p 0001c000 08:01 9785919    /lib/ld-2.9.so
>>> 4001e000-4001f000 r-xp 4001e000 00:00 0          [vdso]
>>> 4001f000-40020000 rw-p 4001f000 00:00 0
>>> 40037000-4016f000 r-xp 00000000 08:01 9784624    /lib/libc-2.9.so
>>> 4016f000-40171000 r--p 00138000 08:01 9784624    /lib/libc-2.9.so
>>> 40171000-40172000 rw-p 0013a000 08:01 9784624    /lib/libc-2.9.so
>>> 40172000-40176000 rw-p 40172000 00:00 0
>>> bfb35000-bfb4a000 rw-p bffeb000 00:00 0          [stack]
>
> there is no continuous block of 2 GiB virtual address space (this is
> because Linux changes the location where libraries are mapped).  When
> you request allocation of 2.5 GiB system has to find a large enough
> hole between allocated regions and there isn't any.  See for
> yourself and analyze the hexadecimal numbers on the left column
>
> On 64-bit systems the problem does not occur because applications
> use larger virtual address (48-bit if I'm not mistaken which is
> 256 TiB)
>
>
> PS. Do not top-post.
>
>
> [1] With Physical Address Extension[2] CPU can address more memory (64 GiB)
> but
>    each application can address up to 4GiB anyways so lets ignore it for
> now.
> [2] http://en.wikipedia.org/wiki/Physical_Address_Extension
>
> --
> Best regards,                                            _     _
>  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
>  ..o | Computer Science,  Micha³ "mina86" Nazarewicz      (o o)
>  ooo +----<mina86@mina86.com>---<mina86@jabber.org>-ooO----(_)--Ooo--
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on 32bit machine
  2009-08-21 11:04       ` Joe
@ 2009-08-21 12:21         ` Michał Nazarewicz
  2009-08-22  7:44         ` Glynn Clements
  1 sibling, 0 replies; 10+ messages in thread
From: Michał Nazarewicz @ 2009-08-21 12:21 UTC (permalink / raw)
  To: Joe; +Cc: Glynn Clements, linux-c-programming

On Fri, 21 Aug 2009 13:04:11 +0200, Joe <longapple@gmail.com> wrote:

> Clear. But how comes 2000MB can be allocated when stack limit is unlimited?
>
> $ ulimit -s
> unlimited
> $ ./malloc 2046
> Malloc succeeded
> $ ./malloc 2047
> malloc failed: Cannot allocate memory           <==== the critical
> point for my case is 2046MB

Because, there is a large enough continuous area in address space.
I'm not sure how to answer that differently.

PS. Again, do not top post and remove unnecessary comments and signatures.

-- 
Best regards,                                            _     _
  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
  ..o | Computer Science,  Micha³ "mina86" Nazarewicz      (o o)
  ooo +----<mina86@mina86.com>---<mina86@jabber.org>-ooO----(_)--Ooo--

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: strange stack limit behavior when allocating more than 2GB mem on  32bit machine
  2009-08-21 11:04       ` Joe
  2009-08-21 12:21         ` Michał Nazarewicz
@ 2009-08-22  7:44         ` Glynn Clements
  1 sibling, 0 replies; 10+ messages in thread
From: Glynn Clements @ 2009-08-22  7:44 UTC (permalink / raw)
  To: Joe; +Cc: Michał Nazarewicz, linux-c-programming


Joe wrote:

> Clear. But how comes 2000MB can be allocated when stack limit is unlimited?

Because malloc() can allocate from the area reserved for the stack. 
The stack limit is a limit, not a reservation.

If you set a small stack limit, there will be ~2.7 GiB below where the
libraries are mapped and very little above it. If you set the stack
limit to "unlimited", there will be ~850 MiB below where the libraries
are mapped and ~2 GiB above it.

malloc() can allocate from either of those areas, but any particular
allocation must fit into one or the other. It can't split a single
allocation between areas, and it can't move any existing mappings.

-- 
Glynn Clements <glynn@gclements.plus.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-08-22  7:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-21  3:47 strange stack limit behavior when allocating more than 2GB mem on 32bit machine Joe
2009-08-21  6:58 ` Glynn Clements
2009-08-21  9:12   ` Joe
2009-08-21  9:37     ` Nicholas Mc Guire
2009-08-21 10:33       ` Michał Nazarewicz
2009-08-21  9:38     ` Michał Nazarewicz
2009-08-21 11:04       ` Joe
2009-08-21 12:21         ` Michał Nazarewicz
2009-08-22  7:44         ` Glynn Clements
2009-08-21  7:09 ` Michał Nazarewicz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.