Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are sbrk/brk implemented in Linux?

Tags:

I was thinking about how the Linux kernel implements system calls and I was wondering if someone could give me a high level view of how sbrk/brk work?

I've reviewed the kernel code, but there is just so much of it and I don't understand it. I was hoping for a summary from someone?

like image 427
samoz Avatar asked Jun 15 '09 17:06

samoz


People also ask

How does brk work in Linux?

brk() sets the end of the data segment to the value specified by addr, when that value is reasonable, the system has enough memory, and the process does not exceed its maximum data size (see setrlimit(2)). sbrk() increments the program's data space by increment bytes.

How is sbrk implemented?

On Linux, sbrk() is implemented as a library function that uses the brk() system call, and does some internal bookkeeping so that it can return the old break value.

What does sbrk do in Linux?

The sbrk() function is used to change the space allocated for the calling process. The change is made by adding incr bytes to the process's break value and allocating the appropriate amount of space. The amount of allocated space increases when incr is positive and decreases when incr is negative.

What is the difference between brk () and sbrk ()?

brk identifies the lowest data segment location not used by the caller as addr . This location is rounded up to the next multiple of the system page size. sbrk , the alternate interface, adds incr bytes to the caller data space and returns a pointer to the start of the new data area.


2 Answers

In a very high level view, the Linux kernel tracks the memory visible to a process as several "memory areas" (struct vm_area_struct). There is also a structure which represents (again in a very high level view) a process' whole address space (struct mm_struct). Each process (except some kernel threads) has exactly one struct mm_struct, which in turn points to all the struct vm_area_struct for the memory it can accesss.

The sys_brk system call (found in mm/mmap.c) simply adjusts some of these memory areas. (sbrk is a glibc wrapper around brk). It does so by comparing the old value of the brk address (found inside struct mm_struct) and the requested value.

It would be simpler to look at the mmap family of functions first, since brk is a special case of it.

like image 114
CesarB Avatar answered Sep 28 '22 06:09

CesarB


you have to understand how virtual memory works, and how an MMU mapping relates to real RAM.

real RAM is divided in pages, traditionally 4kB each. each process has its own MMU mapping, which presents to that process a linear memory space (4GB in 32-bit linux). of course, not all of them is actually allocated. at first, it's almost empty, that is no real page is associated with most addresses.

when the process hits a non-allocated address (either trying to read, write or execute it), the MMU generates a fault (similar to an interrupt), and the VM system is invoked. If it decides that some RAM should be there, it picks an unused RAM page and associates with that address range.

that way, the kernel doesn't care how the process uses memory, and the process doesn't really care how much RAM there is, it will always have the same linear 4GB of address space.

now, the brk/sbrk work at a slightly higher level: in principle any memory address 'beyond' that mark is invalid and won't get a RAM page if accessed, the process would be killed instead. the userspace library manages memory allocations within this limit, and only when needed ask the kernel to increase it.

But even if a process started by setting brk to the maximum allowed, it wouldn't get real RAM pages allocated until it starts accessing all that memory addresses.

like image 44
Javier Avatar answered Sep 28 '22 07:09

Javier