1

In the process address space, there is the stack and the heap. When a function is called, or even when a local variable is declared, it uses the stack; the kernel must assign physical address and create the mapping of virtual to physical address; so, a system call should be involved here, what is going on?

How does stack allocation work in Linux?

The first answer says: "I've found that the stack grows without any system call (according to strace). So, this means that the kernel grows it automatically (this is what the "implicit" means above), i.e. without explicit mmap/mremap from the process." If it is the job of the kernel to "grow" the stack, why is a system call not involved?

When is the heap used for dynamic memory allocation?

For the heap, the first answer says: "A call to malloc does not necessarily result in a call to sbrk or mmap (depending on how Libc implements dynamic memory allocation) to expand the mappings, if a call to malloc can be satisfied by reusing previously freed memory areas." I guess this is the concept of free lists. Is this same concept used for stack allocation?

My basic grievance in both allocations is that physical memory must be allocated, and the mapping from VMA to physical must be created, so a system call should happen. I tried reading the book by Mel Gorman linked in the answer to the first question, but couldn't find anything meaningful to answer my question.

1
  • Why "must" the kernel be involved in the allocation of every single local variable or in every function call? Wouldn't that be rather excessive? Especially considering that regular system calls (like read(2)), appear pretty much as function calls to the application program, how would that even work? Could there be an alternative explanation? Perhaps that the OS actually doesn't need to be involved in the bookkeeping of every single variable separately, but can do with just larger-scale bookkeeping, e.g. on a page or segment level (or what have you)?
    – ilkkachu
    Jan 3 at 15:26

2 Answers 2

0

The kernel grows the stack in response to a page fault triggered when the process tries to write below the bottom of the stack. This doesn’t show up as a system call.

System calls aren’t the only way the kernel can be involved: it also handles faults and interrupts.

5
  • 1. When a process is executed, is a minimal sized stack pre-allocated by kernel (with the VMA to PMA mappings for all pages of this pre-allocated stack made by the kernel)? 2. Since the kernel is involved in growing the stack, a context switch must occur. So, is this operation as expensive as a system call? That is, is there any special difference between the role of a kernel in a system call and in any other functionality of the kernel apart from system call?
    – Dev Jain
    Jan 3 at 17:26
  • 1. Each thread gets its own pre-allocated stack, but it isn’t fully mapped — see this answer for pointers. 2. I haven’t measured but I suspect the cost is similar. In any case if the stack isn’t physically allocated to cover the full use of a thread, then you’ll pay the cost of page faults anyway. Jan 3 at 18:04
  • Thanks, makes sense. Suppose the default stack size is 8 MB. So, less than this is actually "allocated" in form of physical memory, the rest is given as a guarantee to the user that he can use it, but is not actually mapped yet. 1. What is the heuristic/algorithm that determines this pre-mapped minimum? 2. What happens after this 8 MB? Let's say a lot of free memory is available; can kernel grow the stack after this, if this thread demands? That is, can termination of a program(thread) due to "stack overflow" be avoided, or the solution is virtual stack size increase(for this thread only)?
    – Dev Jain
    Jan 4 at 6:55
  • 1. Like other allocations, I suspect nothing is mapped, and pages are mapped as they are used. 2. On Linux, a process segfaults if it runs out of stack. The stack can’t grow — threads all get their stack allocated in the same address space, a thread running out of stack space might need to move another thread’s stack to be able to grow its own. Jan 4 at 13:19
  • I believe this answer of yours is relevant to my problem: unix.stackexchange.com/questions/566273/…
    – Dev Jain
    Jan 22 at 5:43
0

Almost everything you mention is independent of virtual memory. Virtual memory is happening at the same time, independently. With the exception of growing the stack.

When the stack overflows, the kernel can grow the stack. This can be done, by the kernel setting the page beyond the stack to be not-present. When the process tries to access beyond the end of the stock, it reads or writes to this not-present page, causing a page-fault. The kernel then allocates more memory and maps it to this page (and maybe a few more pages), and puts a new not-present page beyond the new end.

Processing the page-fault and processing a sys-call, is almost exactly the same, and will have the same cost. Except the user-mode process, does not need any special instructions. This makes it faster, because most of the time there is no page-fault.

Sys-calls use a trap (the exact instruction depends on processor instruction set) instruction. trap instructions, divide by zero, interrupts, page-faults, and some other things are handled in the same way.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .