![]() ![]() This problem in Linux is addressed using the slab allocator which slices pages into smaller blocks of memory (slabs) for allocation. This is also known as internal fragmentation. This “wastes” 31 pages (i.e., for an allocation of 33 pages, we would have an overhead of 31/64 * 100 = 48\%). Seen as the buddy allocator works with the order queues explained above, the minimum amount of pages we can get is 2^6 = 64 because 33 > 2^5 (=32). The GFP (Get Free Page) mask that is in the alloc_pages signature represents a set of flags that can be combined to represent who requests the memory allocation: e.g., GFP_KERNEL is used when allocating page frames for use in the kernel, GFP_USER is for userspace allocations, etc… (For a complete list of the GFP flags, see include/linux/gfp.h).Īs it might be clear by now, the buddy allocator has one big problem. If the queue is empty, the buddy allocator will search for queues in the bigger “orders” to split a block into two buddies and allocate the requested pages. */ // "linux/page_alloc.c" void free_pages ( unsigned long addr, unsigned int order ) īoth functions take the order as the parameter to see which queue to look for. * e.g., to request one page: struct page *page = alloc_pages(GFP_KERNEL, 0) "linux/gfp.h" static inline struct page * alloc_pages ( gfp_t gfp_mask, unsigned int order ) /* It goes from 0 (min order) to 10 (MAX_ORDER - 1). The buddy allocator keeps track of free areas via an array of “queues” of type struct free_area which keeps track of the free chunks (in reality we are talking about page frames –> struct page). Generally speaking there will be DMA and DMA32 zones, highmem zone and a Normal zone and other zones (e.g., Zone Movable). You are not necessarily expected to understand the notion of a memory zone. ![]() Note: Linux uses a buddy allocator for each memory zone. At a later stage, if and when that memory is free’d, the two buddies (if both free) will coalesce forming a larger chunk of free memory. ![]() At this point, of the two halves, also known as buddies, one will be used to satisfy the allocation request, and the other will remain free. Whenever a block of memory needs to be allocated and the size of it is not available, one big chunk is halved continuously, until a chunk of the correct size is found. Physical memory is broken up into large chunks of memory where each chunk is a “page order” (i.e., 2^n * PAGE_SIZE). The basic idea of a buddy allocator is fairly simple. Normal Pages: 4KB (defined as the PAGE_SIZE constant in the kernel).I will illustrate what happens on x86-64 systems in which the page sizes are: This writeup has been written based on the 5.3.13 Linux kernel (latest stable release at the time of writing - Fri 15 Nov 22:13:). I will briefly explain what the buddy allocator is in order to make it clear why a slab allocator is handy in the linux kernel and then continue with a more detailed explanation of the slab allocator(s). Seeing as the Slab allocator is a fairly hard and advanced topic to grasp but also essential to start programming in the Linux kernel, I wrote this document which explains how it works. If you have any further questions or suggestions after reading this writeup feel free to contact me at or on Twitter ( I will try to answer any questions or adopt any suggestions :) Introduction
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |