Search code examples
clinuxoperating-systemmmu

difference between memory management &memory allocation.do they both work together when allocation/access happens2 memory|how they are exactly related


So I like to know when I call malloc what exactly happens? Since malloc must be a wrapper so some other function must called inside it may be brk or something, But what happens inside brk, all I know these are memory allocation functions that allocate memory and return non zero value if succeed. But then what is memory management.

So management if memory If I assume is simply keeping sizes of memory against there current value. so for example if I have a two malloc calls both are allocation 10 integer each have the size of allocation will be kept against current values in some table..Whats that table is called. So assume I am implementing a memory management unit is making sense. Is there any standard used in Linux for some struct that can be referred to as this table, Can I have multiple memory management units in one system means there is a parent MMU, and my MMU is just depending on some standard functions


Solution

  • When you call malloc() on Linux, you call a thin wrapper in libc (the C standard library implementation). This thin wrapper will often use the mmap system call to get memory allocated.

    On x86-64, system calls are made using syscall in assembly along with some arguments in conventional registers specified in the SysV ABI.

    The syscall instruction makes the processor jump in supervisor mode from user mode at the address specified in the STAR64 MSR register of these processors.

    On Linux, it will jump at the first instruction of the file entry_64.S. This assembly file will make several checkups to determine what user mode is asking and return a value in some registers.

    For mmap, the system call is looking to allocate physical memory and to modify the page tables so that translations from the next portion of virtual memory available will translate to these positions within physical memory. For more info, you can browse my answer at Each program allocates a fixed stack size? Who defines the amount of stack memory for each application running?. The dynamic allocations are done on what's called the heap which can grow as much as there is memory available.

    The libc library will actually allocate memory itself to determine how much memory was allocated to your user mode process. This is required because the granularity of allocation on modern x86-64 is one 4kb page. The libc library will thus keep track in what's called "arenas" of the pages that were allocated to try and give you new allocations in those pages instead of requesting new ones.

    Also, the Linux kernel keeps track of what memory was allocated to your process in the PCB (the task_struct) in the mm field which is a complex struct in itself.

    EDIT

    I like to know does every allocation is against specific tid/pid and this allocated memory plus pid is saved in some table. Is this the work of MMU

    To understand the concepts in this answer, you need to understand about paging. With paging, every process/thread gets its own set of page tables. Each set of page tables permits access to the whole virtual memory space which is sizable because, on most OS, 48 bits are used which allows to address 2^48 bytes (this is determined by the CPU architecture but there is also a 57 bits address space available on newer CPUs which most OS don't use).

    The MMU doesn't know anything about processes/threads or PIDs. It blindly takes the virtual addresses and crosses the page tables to translate them to physical ones. Most entries in the page tables are zeroed out to make sure that an access will trigger an hardware interrupt (a page fault). On page fault, the Linux kernel will cross the mm field of the process which triggered the page fault and kill the process if its memory access was outside that region. Each core sees the full physical address space and probably has its own MMU. The MMU does have PCID now but it is mostly cache related which isn't really related to your question.

    Every core of the processor runs only one thread at a time and has its own CR3 register. An OS knows what process runs where and on what core because the different fault handlers run in kernel mode and have access to all the global structures of the kernel which identify which process runs where and etc. The translations using the page tables start with the CR3 register. The OS simply saves the value of the CR3 register in the PCB and restores it on context switch.

    Hope this is clear! For more info about paging see: What is paging exactly? OSDEV.