How to get memory address from memfd_create?

爷,独闯天下 提交于 2020-02-21 06:30:27

问题


In my application I need to share memory between parent and child (using fork+execl). I use memfd_create to allocate memory, because it provides a file descriptor, which may be conveniently used in child process (the discriptor is tied to stdin via dup2 before execl) to attach to the allocated memory.

I do not use write and read - I use pointers to read and write memory directly.

The only piece of the puzzle which is left to solve is how to get the address of memory, allocated via fd = memfd_create ....

Using mmap is undesirable, because it duplicates the memory, instead of giving the memory address already allocated by memfd_create.

This is demonstrated by the following code. In its output each mmap address is incremented by 4096, which is the size of memory, referred to by fd:

0x7f98411c1000
0x7f98411c0000

whereas if mmap had given the direct address, addresses in the output would be the same.

#include <stdio.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(void)
{
    int fd = syscall(SYS_memfd_create, "shm", 0);
    if (fd == -1) return 1;

    size_t size = 4096; /* minimal */

    int check = ftruncate(fd, size);
    if (check == -1) return 1;

    void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (ptr == MAP_FAILED) return 1;

    void *ptr2 = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (ptr2 == MAP_FAILED) return 1;

    printf("%p\n%p\n", ptr, ptr2);

    return 0;
}

So, how to get direct address, avoiding memory duplication by mmap?


回答1:


Not sure if you still need an answer, since you have written the main point in your own answer, but just adding this to be sure it is complete:

memfd_create creates a memory-only file (meaning it is not stored on disk, although it can be swapped out). As you write in your answer, it returns a file descriptor.

mmap ensures that the file behind a file descriptor is in memory (which requires no action in case of a memory-only file), and gives you a pointer to that memory. It does not copy the memory (except from disk to memory when mapping a file from disk). If the same file is mapped multiple times, each call to mmap reserves a new region of virtual memory, but all those regions access the same portion of physical memory.

So the short answer to your question is that you misunderstand mmap; it does not copy the memory, and it is the perfect solution to your problem.




回答2:


Instead of physical address we get a file descriptor from memfd_create. File descriptor is a handle through which we get access to the memory (i.e., it is a mapping from file discriptor to memory). A file descriptor is more convenient to work with, than memory address: it can be passed to forked processes, etc (see OP).

mmap just maps physical address (referred to by file descriptor) to a virtual address. A virtual memory address is in fact the memory address, because user never sees physical addresses. Each mmap call returns a different virtual address, all of which are mapped to the same physical address by the kernel.



来源:https://stackoverflow.com/questions/49567475/how-to-get-memory-address-from-memfd-create

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!