Hello,

The mmap man page says:
"If the MAP_FIXED flag is specified, the allocation will happen
at the specified address, replacing any previously established mappings
in its range."

However, a simple:

#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>

int main(void)
{
  void *ptr0;
  void *ptr1;

  ptr0 = mmap(0, 510 * 1024 * 1024,
              PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  if (ptr0 == MAP_FAILED)
    err(1, "first mmap():");
  ptr1 = mmap(ptr0, 510 * 1024 * 1024,
PROT_READ|PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  if (ptr1 == MAP_FAILED)
    err(1, "second mmap():");
}

fails on the second mmap with ENOMEM (with a data limit of 512M).
It is my understanding from the man page that it should not happen, as it
is supposed to replace the old mapping, thus not taking more memory.

Is my understanding correct, or did I miss something ?

In uvm_mmap.c:

if ((flags & MAP_ANON) != 0 || (flags & __MAP_NOFAULT) != 0 ||
((flags & MAP_PRIVATE) != 0 && (prot & PROT_WRITE) != 0)) {
                        if (p->p_rlimit[RLIMIT_DATA].rlim_cur < size ||
                            p->p_rlimit[RLIMIT_DATA].rlim_cur - size <
                            ptoa(p->p_vmspace->vm_dused)) {
                                return ENOMEM;
                        }
                }
                maxprot = PROT_MASK;
error = uvm_mmapanon(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
                    flags, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur, p);

The size check is done without looking at a possible
replacement. What would be the best way to add this lookup without
duplicating code (maybe uvm_map_isavail()) too much ?

Mickael

Reply via email to