[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: When should ralloc.c be used?
From: |
Daniel Colascione |
Subject: |
Re: When should ralloc.c be used? |
Date: |
Fri, 28 Oct 2016 01:44:33 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 |
On 10/28/2016 01:27 AM, Eli Zaretskii wrote:
Cc: address@hidden, address@hidden, address@hidden
From: Daniel Colascione <address@hidden>
Date: Fri, 28 Oct 2016 01:11:08 -0700
Say I mmap (anonymously, for simplicity) a page PROT_NONE. After the
initial mapping, that address space is unavailable for other uses. But
because the page protections are PROT_NONE, my program has no legal
right to access that page, so the OS doesn't have to guarantee that it
can find a physical page to back that page I've mmaped. In this state,
the memory is reserved.
The 20GB PROT_NONE address space reservation itself requires very little
memory. It's just a note in the kernel's VM interval tree that says "the
addresses in range [0x20000, 0x500020000) are reserved". Virtual memory is
Now imagine I change the protections to PROT_READ|PROT_WRITE --- once
the PROT_READ|PROT_WRITE mprotect succeeds, my program has every right
to access that page; under a strict accounting scheme (that is, without
overcommit), the OS has to guarantee that it'll be able to go find a
physical page to back that virtual page. In this state, the memory is
committed -- the kernel has committed to finding backing storage for
that page at some point when the current process tries to access it.
I'm with you up to here. My question is whether PROT_READ|PROT_WRITE
call could fail after PROT_NONE succeeded. You seem to say it could;
I thought it couldn't.
Yes, it can fail. This program just failed on my system, which is a
strict accounting (echo 2 > /proc/sys/vm/overcommit_memory) Linux box
with much less than 100GB total commit available.
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
size_t GB = (size_t) 1024 * 1024 * 1024;
int
main()
{
size_t sz = 100*GB;
void* mem = mmap(NULL, sz, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED) {
fprintf(stderr, "map failed: %s\n", strerror(errno));
return 1;
}
if (mprotect(mem, sz, PROT_READ|PROT_WRITE)) {
fprintf(stderr, "mprotect failed: %s\n", strerror(errno));
return 1;
}
fprintf(stderr, "mprotect worked\n");
return 0;
}
Say you have a strict-accounting system with 1GB of RAM and 1GB of swap.
I can write a program that reserves 20GB of address space.
I thought such a reservation should fail, because you don't have
enough virtual memory for 20GB of addresses. IOW, I thought the
ability to reserve address space is restricted by the actual amount of
virtual memory available on the system at the time of the call. You
seem to say I was wrong.
I'm not sure you're even wrong :-) What does "virtual memory" mean to
you? I'm not sure what you have in mind maps to any of the concepts I'm
using.
When we allocate memory, we can consume two resources: address space and
commit. That 100GB mmap above doesn't consume virtual memory, but it
does consume address space. Address space is a finite resource, but
usually much larger than commit, which is the sum of RAM and swap space.
When you commit a page, the resource you're consuming is commit.
(Technically, the 100GB mapping consumes real memory enough for the OS
to remember you've set aside that address space, but it's usually a
negligible book-keeping note. On my system, I can make sz equal to 80TB
or so before the mmap starts to fail: that's about the size of the
address space range dictated by amd64 processor design.)
(In a 32-bit process on modern systems, it's frequently the case that
you have more commit on the system than any one process has address space.)
- Re: When should ralloc.c be used?, (continued)
- Re: When should ralloc.c be used?, Eli Zaretskii, 2016/10/24
- Re: When should ralloc.c be used?, Richard Stallman, 2016/10/24
- Re: When should ralloc.c be used?, Stefan Monnier, 2016/10/25
- Re: When should ralloc.c be used?, Stefan Monnier, 2016/10/25
- Re: When should ralloc.c be used?, Jérémie Courrèges-Anglas, 2016/10/28
- Re: When should ralloc.c be used?, Daniel Colascione, 2016/10/28
- Re: When should ralloc.c be used?, Jérémie Courrèges-Anglas, 2016/10/28
- Re: When should ralloc.c be used?, Eli Zaretskii, 2016/10/28
- Re: When should ralloc.c be used?, Daniel Colascione, 2016/10/28
- Re: When should ralloc.c be used?, Eli Zaretskii, 2016/10/28
- Re: When should ralloc.c be used?,
Daniel Colascione <=
- Re: When should ralloc.c be used?, Eli Zaretskii, 2016/10/28
- Re: When should ralloc.c be used?, Daniel Colascione, 2016/10/28
- Re: When should ralloc.c be used?, Eli Zaretskii, 2016/10/28
- Re: When should ralloc.c be used?, Stefan Monnier, 2016/10/28
- Re: When should ralloc.c be used?, Eli Zaretskii, 2016/10/28
- Re: When should ralloc.c be used?, Stefan Monnier, 2016/10/28
- Re: When should ralloc.c be used?, Daniel Colascione, 2016/10/28
- Re: When should ralloc.c be used?, Eli Zaretskii, 2016/10/29
- Re: When should ralloc.c be used?, Daniel Colascione, 2016/10/29
- Re: When should ralloc.c be used?, Stefan Monnier, 2016/10/28