Re: ENOMEM with mmap in IA64



iam.techy@xxxxxxxxx wrote:
Hi,
I am calling mmap for certain binaries in a loop (inside the same
process), and I am getting ENOMEM while mapping the 2nd or 3rd binary
(not the first one).. Here is the sample scenerio -

foo(char *fname)
{
struct stat sbuf;
fd = open(fname, O_RDONLY);
/* exit if fail */

stat(fname, &sbuf);
/* exit if fail */

file_size = sbuf.st_size;

buffer = mmap(0, file_size, PROT_READ, MAP_SHARED, fd, 0);
if (buffer == MAP_FAIL) {
/* Exit */
}

/* DO SOMETHINGS with buffer */

munmap(buffer, file_size);
}

I am calling this function for various binaries (system binaries) in a
loop, and I get ENOMEM after successfully crossing 2-3 binaries
........ I didnt understand the reason.
I also tried with MAP_PRIVATE, surprisingly I didnt get ENOMEM after
processing some 15-20 binaries... (didnt check after that).. But why
should it matter if I am not writing to the region ?

If you're "Doing somethings with buffer" you are writing to the
region -- but I don't think that's your problem per se.

There are a few possiblities (and note that I'm assuming
your sample code is reflective of your real code and you operate
on a single mapping at a time, unmapping when done -- if you
leave the shared mmaps around, you're probably just plain
exhausting shared address space anyway):

1) You have sufficient shared address space, the file is
not currently mapped by another process as a shared object -
but the shared address space you have is too fragmented to
find a contiguous range in the size requested.

2) You just plain don't have enough shared address space
period.

3) You aren't out of shared address space, but the file
*is* already mapped by another context, your mapping request
is a superset of the already existing mapping [i.e. you need to
expand the existing mapping] and there is not free shared
address space available to do so. (i.e. You're trying to map
6 pages at offset X. Process B has 2 pages mapped at offset X.
Virtual addres Y is the current shared mapping of X to X + 1.
X+2 (or some offset before X + 5) is already in use for a
different file or a non-contiguous offset of the same file.
You can't expand the mapping at Y to cover your range -- so
the mapping request fails).

Private mappings work in these cases because they're in a completely
different address space which is consumed only by the process doing
the mapping. Hence you tend to have more resources, less fragmentation
and if the file is already mapped as shared by another context, you get
a unique private mapping which has nothing to do with the shared mapping
anyway (making scenario 3 moot).

If you're in one of these cases on IPF you have a few options:

1) Use MPAS (see http://docs.hp.com/en/5990-6737/5990-6737.pdf for
more details) the Mostly Private Address Space model in HP-UX.
Note that lots of MPAS usage can degrade system performance - so
use your best judgement here.

2) Go 64-bit if you're 32-bit. 64-bit shared address space is much, much
larger -- there shouldn't be a problem unless you're in case (3). Case
(3) requires MPAS if you want to be able to write to the file and have
those changes written to the actual file. If you want to work with a
copy of the file [you're only reading, or you may write but those writes
are in effect on a temporary version of the file] you can just map the
file private.

3) Look into chatr/Memory Windows options to move your process to a
different shared address space than the default (global) shared address
space.

Don


Is there something which I am missing ?

Thanks

.



Relevant Pages

  • [PATCH] Make MTD chardev mmap available under some circumstances
    ... Make it possible to mmap MTD chardevs directly or by copy on a NOMMU system. ... Presenting backing device capabilities for MTD character device files to ... One to indicate that a device supports direct mapping with both read ... writable and executable shared and private mappings. ...
    (Linux-Kernel)
  • Re: process creation time increases linearly with shmem
    ... VM_MAYSHARE is a sign of the mapping being a shared mapping. ... So I really think you need to verify that it's a file mapping too. ... about private mappings that haven't been COW'ed? ... send the line "unsubscribe linux-kernel" in ...
    (Linux-Kernel)