2

It is an useful feature for systems which are using (...still have to use) 32-bit binaries, and the 4G limit came into consideration.

It essentially means, that the 32-bit user-space code, the 32-bit user-space data and the (32-bit with PAE, or 64-bit) kernel live in different address spaces, which essentially enables for the processes to use nearly all of the possible maximal 4G address space for their data.

Except some ancient announcements, unfortunately I couldn't find from it any more:

I am pleased to announce the first public release of the "4GB/4GB VM split" patch, for the 2.5.74 Linux kernel:

http://redhat.com/~mingo/4g-patches/4g-2.5.74-F8

The 4G/4G split feature is primarily intended for large-RAM x86 systems, which want to (or have to) get more kernel/user VM, at the expense of per-syscall TLB-flush overhead.

On x86, the total amount of virtual memory - as we all know - is limited to 4GB. Of this total 4GB VM, userspace uses 3GB (0x00000000-0xbfffffff), the kernel uses 1GB (0xc0000000-0xffffffff). This is VM scheme is called the 3/1 split. This split works perfecly fine up until 1 GB of RAM - and it works adequately well even after that, due to 'highmem', which moves various larger caches (and objects) into the high memory area.

On my tests, some of my processes start to dying roughly at 2-3 GB.

How could I do achieve this? I use a relative recent kernel (4.10). I can use a 64-bit kernel on a 32-bit user space or use a 32-bit PAE kernel.

It is enough, if only some of the processes use 4G/4G, but they seem to really need it.

  • You would need to patch the kernel. To my knowledge, the 4G/4G split was never released in the official kernel, and I doubt you will find a patch that applies to a modern kernel. I guess the 33 % improvement over the 3/1 split was not worth it, especially after 64-bit CPUs became the norm. – Johan Myréen Aug 24 '17 at 18:37
1

On a 64-bit kernel you already have full 4G accessible by a 32-bit userspace program. See yourself by entering the following in the terminal (WARNING: your system may become unresponsive if it doesn't have free 4GiB of RAM when running this):

cd /tmp
cat > test.c <<"EOF"
#include <stdlib.h>
#include <stdio.h>
int main()
{
    size_t allocated=0;
    while(1)
    {
        const size_t chunkSize=4096;
        char* p=malloc(chunkSize);
        if(!p) return 0;
        *p=1;
        allocated+=chunkSize;
        printf("%zu\n",allocated);
    }
    return 0;
}
EOF
gcc test.c -o test -m32 && ./test | tail -n1

On my x86_64 kernel 3.12.18 I get 4282097664 as the result, which is about 4GiB-12.3MiB, so it's fair to consider 4G/xG split achieved.

  • Wow! Nice to know. It is a perfectly acceptable compromise. – peterh Jan 21 '18 at 3:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.