Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

The Linux Kernel/Memory

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

memoryProcessesvirtual memorymemory mapping demand paging and swaplogical memoryPage Allocatorpages The kernel has full access to the system's memory and allows processes to Process isolation safely access this memory as they require it. Often the first step in doing this is Virtual address space virtual addressing, usually achieved by paging and/or segmentation. Virtual addressing allows the kernel to make a given physical address appear to be another address, the virtual address. Virtual address spaces may be different for different processes; the memory that one process accesses at a particular (virtual) address may be different memory from what another process accesses at the same address. This allows every program to behave as if it is the only one (apart from the kernel) running and thus prevents applications from crashing each other. On many systems, a program's virtual address may refer to data which is not currently in memory. The layer of indirection provided by virtual addressing allows the operating system to use other data stores, like a hard drive, to store what would otherwise have to remain in main random-access memory (RAM). As a result, operating systems can allow programs to use more memory than the system has physically available. When a program needs data which is not currently in RAM, the Memory management unit MMU Page fault signals to the kernel that this has happened, and the kernel responds by writing the contents of an inactive memory block to disk (if necessary) and replacing it with the data requested by the program. The program can then be resumed from the point where it was stopped. This scheme is generally known as demand paging. Virtual addressing also allows creation of virtual partitions of memory in two disjointed areas, one being reserved for the kernel (kernel space) and the other for the applications (user space). The applications are not permitted by the processor to address kernel memory, thus preventing an application from damaging the running kernel. This fundamental partition of memory space has contributed much to the current designs of actual general-purpose kernels and is almost universal in such systems, Linux being one of them. ⚲ Shell interfaces cat /proc/meminfo 1 free 8 vmstat 1 lsmem – list memory ranges and their online state /proc/pagetypeinfo – page allocator fragmentation info per zone and migrate type /sys/kernel/mm/ksm/ – Kernel Same-page Merging admin-guide/mm/ksm.html tunables (pages_shared, pages_sharing, run) /sys/kernel/mm/lru_gen/enabled – Multi-Gen LRU admin-guide/mm/multigen_lru.html (since 6.1) sos memory plugin – diagnostics collection for memory subsystem Optimizing memory access, RHEL Memory management API ⚲ 2 brk ↪ sys_brk, do_brk_flags dynamically changes data segment size of the calling process. The change is made by resetting the program break of the process, which determines the maximum space that can be allocated. The program break is the address of the first location beyond the current end of the data region, and determines the maximum space that can be allocated by the process. The amount of available space increases as the break value increases. The added available space is initialized to a value of zero. ⚲ 2 mmap ↪ ksys_mmap_pgoff maps files or devices into memory. It is a method of memory-mapped file I/O. It naturally implements demand paging, because file contents are not read from disk initially and do not use physical RAM at all. The actual reads from disk are performed in a "lazy" manner, after a specific location is accessed. After the memory is no longer needed it is important to 2 munmap the pointers to it. Protection information can be managed using 2 mprotect ↪ do_mprotect_pkey and special treatment can be enforced using 2 madvise ↪ do_madvise. 2 process_madvise ↪ sys_process_madvise – give memory hints to another process (since 5.10) 2 memfd_secret ↪ sys_memfd_secret – create memory hidden from the kernel itself (since 5.14) 2 mseal ↪ sys_mseal – seal memory mappings against modifications (since 6.10) In Linux, 2 mmap can create several types of mappings, such as anonymous mappings, shared mappings and private mappings. Using the MAP_ANONYMOUS flag mmap() can map a specific area of the process's virtual memory not backed by any file, whose contents are initialized to zero. These functions are typically called from a higher-level memory management library function such as C standard library 3 malloc or C++ new operator. ⚲ API linux/uaccess.h – user-space memory access and validation helpers linux/mm.h – memory management declarations and page handling APIs rust/kernel/mm.rs – Rust bindings linux/slab.h – memory allocation APIs for slab and kmalloc systems 💾 History: Two basic related to memory management system calls brk and mmap Linux inherits from Unix. BTW: On Linux, 2 sbrk is not a separate system call, but a C library function that also calls to sys_brk and keeps some internal state to return the previous break value. 📚 References Memory Management APIs core-api/mm-api.html x86_64 Memory Management x86/x86_64/mm.html sbrk mmap Memory management ⚙️ Internals: sys_brk ↯ call hierarchy: do_brk_flags vm_area_alloc kmem_cache_alloc kmem_cache_alloc_lru 🔨 stress-ng --brk, --bigheap, --vm, --mmap Virtual memory 🔧 TODO: Virtual memory Virtually contiguous memory on top of physical and swapped memory pages. 🗝️ Acronyms: VPFN - Virtual Page Frame Number PFN - Physical Page Frame Number pgd - Page Directory pmd - Page Middle Directory pud - Page Upper Directory pte - Page table Entry VMA - Virtual Memory Area, see vm_area_struct TLB - Translation Lookaside Buffer MMU - Memory Management Unit ⚲ API: linux/vmalloc.h vmalloc vfree linux/cleanup.h – scope-based cleanup helpers scoped_guard /proc/vmallocinfo ⚙️ Internals: vm_struct virt_to_page vmalloc_init find_vma mm/vmalloc.c – virtually contiguous memory allocator 📚 References Virtually Contiguous Mappings core-api/mm-api.html#virtually-contiguous-mappings Page Tables mm/page_tables.html Scope-based Cleanup Helpers core-api/cleanup.html Data types Pointers and addresses Kernel-specific address types, in addition to common C pointers. unsigned long – used to store addresses that are not intended to be dereferenced by the user uintptr_t – to be used in ioctl phys_addr_t – physical address dma_addr_t – DMA address 📚 Further reading (How to avoid) Botching up ioctls process/botching-up-ioctls.html Data Size Neutrality and 64-bit Support Other types ⚲ API linux/types.h – fixed-width and kernel-specific type definitions linux/string.h – standard string manipulation functions bit operations linux/bitfield.h – defining and extracting bitfield values linux/bitops.h – atomic and non-atomic bit manipulation operations linux/bitmap.h – bit arrays that consume one or more unsigned longs linux/sbitmap.h – fast and scalable bitmaps linux/kref.h acpi/actypes.h – common data types for the entire ACPI subsystem linux/list.h – circular doubly linked list implementation list_head – common double linked list list_add ... linux/klist.h – some klist_node->kref helpers klist_add_tail ... linux/kobject.h linux/circ_buf.h linux/kfifo.h – generic kernel FIFO kfifo_in ... linux/rbtree.h – Red-black trees rb_node linux/scatterlist.h scatterlist 👁 Example: samples/kfifo/dma-example.c linux/idr.h – ID allocation linux/container_of.h 📖 References List Management Functions core-api/kernel-api.html#list-management-functions FIFO Buffer core-api/kernel-api.html#fifo-buffer Data structures and low-level utilities core-api#data-structures-and-low-level-utilities Everything you never wanted to know about kobjects, ksets, and ktypes core-api/kobject.html Adding reference counters (krefs) to kernel objects core-api/kref.html Generic Associative Array Implementation core-api/assoc_array.html XArray core-api/xarray.html ID Allocation core-api/idr.html Circular Buffers core-api/circular-buffers.html Red-black Trees (rbtree) in Linux core-api/rbtree.html Generic radix trees/sparse arrays core-api/generic-radix-tree.html Generic bitfield packing and unpacking functions core-api/packing.html How to access I/O mapped memory from within device drivers core-api/bus-virt-phys-mapping.html this_cpu operations core-api/this_cpu_ops.html The errseq_t datatype core-api/errseq.html 📚 Further reading Data Structures in the Linux Kernel https://kernelnewbies.org/InternalKernelDataTypes Memory mapping 🔧 TODO ⚲ API: 2 mmap ↪ ksys_mmap_pgoff ↪ do_mmap 2 mprotect 2 mmap2 2 mincore 2 mremap – remap virtual memory address 2 msync – synchronize memory-mapped file with storage 2 posix_fadvise – predeclare access pattern for file data linux/mm_types.h – mm_struct, vm_area_struct linux/mm.h remap_pfn_range SetPageReserved, ClearPageReserved ⚙️ Internals: mm/mmap.c – memory mapping implementation mm/madvise.c – 2 madvise memory usage hints 🔨 stress-ng --madvise 📚 References: mmap Maple Tree core-api/maple_tree.html Memory mapping, linux-kernel-labs vDSO VDSO (virtual Dynamic Shared Object) is a kernel-mapped page in every process that allows userspace to call certain system functions (clock_gettime, gettimeofday) without a syscall. The kernel updates the vDSO data page on every timekeeping tick via update_vsyscall. ⚲ API 7 vdso vdso/datapage.h – vdso_data ⚙️ Internals kernel/time/vsyscall.c – vDSO time data updates arch/x86/entry/vdso – x86 vDSO implementation 📖 References vDSO ABI admin-guide/abi-stable.html#vdso Swap When physical memory is full, the kernel moves inactive pages to a Paging swap area on disk to free memory for active processes. When a process accesses a swapped-out page, a Page fault page fault brings it back. The balance between keeping pages in RAM and swapping is controlled by the vm_swappiness parameter. Memory locking (2 mlock) prevents specific pages from being swapped, which is critical for real-time and security-sensitive applications. ⚲ API: /proc/sys/vm/swappiness – tendency to swap out pages (0–200, default 60; 0 = prefer keeping in RAM) /proc/swaps, swapon -s – list active swap areas 2 swapon, 2 swapoff 8 mkswap – create swap area 2 mlock, 2 mlock2 2 mlockall, 2 munlockall – lock/unlock all pages 2 shmctl ⚙️ Internals: linux/swap.h mm/swapfile.c – swap area management: swapon/swapoff, slot allocation. Not to be confused with mm/swap.c – page LRU list movement and reference counting. 2 swapon ↪ sys_swapon 2 swapoff ↪ sys_swapoff swap_info_struct, si_swapinfo, swap_info vm_swappiness mm/swap_state.c – swap cache, tracks pages in transit to/from swap mm/page_io.c – actual I/O to/from swap device (swap_read_folio, swap_writeout) mm/vmscan.c – Page replacement algorithm page reclaim and scanning wakeup_kswapd ↪ kswapd handle_pte_fault ↪ do_swap_page mm/mlock.c – memory locking 2 mlock ↪ do_mlock 2 shmctl ↪ shmctl_do_lock mm/readahead.c – page readahead for sequential file access linux/zswap.h, mm/zswap.c – Zswap compressed swap cache mm/memcontrol.c – per-cgroup swap accounting, see Memory cgroup controller 🔨 stress-ng --mlock 📚 References: Memory_paging#Linux Memory paging https://wiki.archlinux.org/title/swap Logical memory ⚲ kmalloc is the normal method of allocating memory in the kernel for objects smaller than the page size. It is defined in linux/slab.h. The first argument size is the size (in bytes) of the block of memory to be allocated. The second argument flags are the allocation flags or GFP flags, a set of macros that the caller provides to control the type of requested memory. The most commonly used values for flags are GFP_KERNEL and GFP_ATOMIC, but there is more to be considered. Memory-allocation requests in the kernel are always qualified by a set of GFP flags ("GFP" initially came from "get free page") describing what can and cannot be done to satisfy the request. The most commonly used flags are GFP_ATOMIC and GFP_KERNEL, though they are actually built up from lower-level flags. The full set of flags is huge; they can be found in the linux/gfp.h header file. ⚲ API: ↯ RAII allocation functions hierarchy from linux/device.h: devm_kcalloc - zeroed array devm_kmalloc_array devm_kmalloc - common allocation devm_kzalloc - zeroed allocation devm_kmalloc - common allocation Classic direct API: linux/slab.h kmalloc, kfree Slab allocation Slab allocation is a memory management algorithm intended for the efficient memory allocation of kernel objects. It eliminates fragmentation caused by allocations and deallocations. The technique is used to retain allocated memory that contains a data object of a certain type for reuse upon subsequent allocations of objects of the same type. Basics This section is about the SLUB allocator implementation A slab can be thought of as an array of objects of certain type or with the same size, spanning through one or more contiguous pages of memory; for example, the slab named "task_struct" holds objects of struct task_struct type, used by the scheduling subsystem. Other slabs store objects used by other subsystems, and there is also slabs for dynamic allocations inside the kernel, such as the "kmalloc-64" slab that holds up to 64-byte chunks requested via kmalloc() calls. In a slab, each object can be allocated and freed separately. The primary motivation for slab allocation is that the initialization and destruction of kernel data objects can actually outweigh the cost of allocating memory for them. As object creation and deletion are widely employed by the kernel, overhead costs of initialization can result in significant performance drops. The notion of object caching was therefore introduced in order to avoid the invocation of functions used to initialize object state. With slab allocation, memory chunks suitable to fit data objects of certain type or size are preallocated. The slab allocator keeps track of these chunks, known as caches kmalloc_caches, so that when a request to allocate memory for a data object of a certain type is received, it can instantly satisfy the request with an already allocated slot via slab_alloc_node. Deallocation of the object with kfree does not free up the memory, but only opens a slot which is returned to the slab allocator's free list. The next call to allocate memory of the same size will return the now unused memory slot. See slab_alloc_node/___slab_alloc. This process eliminates the need to search for suitable memory space and greatly alleviates memory fragmentation. In this context, a slab is one or more contiguous pages in the memory containing pre-allocated memory chunks. Slab allocation provides a kind of front-end to the zoned buddy allocator for those sections of the kernel that require more flexible memory allocation than the standard 4KB page size. ⚲ Interface: sudo cat /proc/slabinfo linux/slab.h kmem_cache_alloc, kmem_cache_free 1 slabtop ⚙️ Internals: mm/slab_common.c – slab allocator common code mm_init is called from start_kernel kmem_cache_init create_kmalloc_caches kasan_slab_alloc SLUB allocator – default Unqueued allocator SLUB (software) SLUB is the iteration of the original SLAB allocator that replaced it and became the Linux default allocator since 2.6.23. ⚙️ Internals: mm/slub.c 📚 References: CONFIG_SLUB 💾 Historical: SLOB (Simple List Of Blocks) allocator for embedded devices was removed in kernel 6.4. SLAB allocator, the original slab allocation implementation based on Jeff Bonwick's 1994 paper, was removed in kernel 6.8. SLUB is now the only slab allocator in the kernel. Per-CPU allocator linux/percpu.h, mm/percpu.c – per-CPU memory areas, used by slab and counters 📚 References for Slab allocation: KASAN - KernelAddressSANitizer dev-tools/kasan.html - dynamic memory safety error detector designed to find out-of-bound and use-after-free bugs Video "SL[AUO]B: Kernel memory allocator design and philosophy" Christopher Lameter (Linux.conf.au 2015 conference) Slides Page Allocator The page allocator (or "zoned buddy allocator") is a low-level allocator that deals with physical memory. It delivers physical pages (usually with a size of 4096 bytes) of free memory to high-level memory consumers such as the slab allocators and kmalloc(). As the ultimate source of memory in the system, the page allocator must ensure that memory is always available, since a failure providing memory to a critical kernel subsystem can lead to a general system failure or a kernel panic. The page allocator divides physical memory into "zones", each of which corresponds to zone_type with specific characteristics. ZONE_DMA contains memory at the bottom of the address range for use by severely challenged devices, for example, while ZONE_NORMAL may contain most memory on the system. 32-bit systems have a ZONE_HIGHMEM for memory that is not directly mapped into the kernel's address space. Depending on the characteristics of any given allocation request, the page allocator will search the available zones in a specific priority order. For the curious, /proc/zoneinfo gives a lot of information about the zones in use on any given system. Within a zone, memory is grouped into page blocks, each of which can be marked with a migration type - migratetype describing how the block should be allocated. ⚲ API: cat /proc/buddyinfo linux/gfp.h linux/mmzone.h devm_get_free_pages - RAII function __get_free_pages alloc_page alloc_pages alloc_pages_node ⚙️ Internals: build_all_zonelists is called from start_kernel, ↯ call hierarchy: build_all_zonelists_init __build_all_zonelists build_zonelists __alloc_pages - the 'heart' of the zoned buddy allocator struct zone free_area mm/mmzone.c – memory zone helpers mm/page_alloc.c – buddy page allocator 📚 References: Get Free Page flags core-api/memory-allocation.html Buddy memory allocation Page replacement algorithm OOM killer The Out of memory Out-Of-Memory killer is invoked when the kernel cannot satisfy a memory allocation and all reclaim attempts have failed. It selects a process to kill based on a badness score to free memory and keep the system running. ⚲ API: /proc/$pid/oom_score – current badness score /proc/$pid/oom_score_adj – adjust score (-1000 to 1000) /proc/$pid/oom_adj – deprecated, use oom_score_adj /proc/sys/vm/panic_on_oom ⚙️ Internals: mm/oom_kill.c – out-of-memory killer out_of_memory – main entry point oom_badness – calculates badness score oom_kill_process 📚 References: OOM admin-guide/sysctl/vm.html Managing OOM states for RT, RHEL 🔨 stress-ng --oom-pipe Memory cgroup controller The memory cgroup controller limits and accounts memory usage per group of processes. It can set hard and soft limits, trigger per-cgroup OOM, and track swap usage. ⚲ API: memory.max – hard memory limit memory.high – throttling threshold memory.current – current usage memory.swap.max – swap limit See CGroup v2 Memory controller for full interface ⚙️ Internals: mm/memcontrol.c – memory cgroup controller mem_cgroup – main structure mem_cgroup_charge mem_cgroup_oom 📚 References: Memory Resource Controller admin-guide/cgroup-v2.html#memory tmpfs/shmem linux/shmem_fs.h, mm/shmem.c – tmpfs virtual memory filesystem, also backs POSIX shared memory and 2 memfd_create. KSM linux/ksm.h, mm/ksm.c – Kernel Same-page Merging, deduplicates identical anonymous pages, used by Kernel-based Virtual Machine KVM. KSM admin-guide/mm/ksm.html userfaultfd 2 userfaultfd ↪ mm/userfaultfd.c – handles page faults in user space, used for VM live migration. Userfaultfd admin-guide/mm/userfaultfd.html 🔨 stress-ng --userfaultfd DAMON Data Access MONitor (since 5.15) provides kernel-level data access pattern monitoring. It can be used for memory management optimization and profiling. ⚲ API: /sys/kernel/mm/damon/ linux/damon.h ⚙️ Internals: mm/damon – DAMON core and operation schemes 📖 References: DAMON mm/damon 📚 References for logical memory: Memory Allocation Guide core-api/memory-allocation.html Selecting memory allocator core-api/memory-allocation.html#selecting-memory-allocator Physical memory Memory Layout A 32-bit processor can address a maximum of 4GB of memory. Linux kernels split the 4GB address space between user processes and the kernel; under the most common configuration, the first 3GB of the 32-bit range are given over to user space, and the kernel gets the final 1GB starting at 0xc0000000. Sharing the address space gives a number of performance benefits; in particular, the hardware's address translation buffer can be shared between the kernel and user space. In x86-64 - CONFIG_X86_64 with 4-level page tables (CONFIG_X86_5LEVEL=n), only the least significant 48 bits of a virtual memory address would actually be used in address translation (page table lookup). The remainder bits 48 through 63 of any virtual address must be copies of bit 47, or the processor will raise an exception. Addresses complying with this rule are referred to as "canonical form." Canonical form addresses run from 0 through 00007FFF'FFFFFFFF, and from FFFF8000'00000000 through FFFFFFFF'FFFFFFFF, for a total of 256 TB of usable virtual address space. This is still approximately 64,000 times the virtual address space on 32-bit machines. Linux takes the higher-addressed half of the address space for itself (kernel space) and leaves the lower-addressed half for user space. The "canonical address" design has, in effect, two memory halves: the lower half starts at 00000000'00000000 and "grows upwards" as more virtual address bits become available, while the higher half is "docked" to the top of the address space and grows downwards. +Start addrOffsetEnd addrSizeVM area description 0000'8000'0000'0000 +128 TB ffff'7fff'ffff'ffff ... huge, almost 64 bits wide hole of non-canonical virtual memory addresses up to the -128 TB starting offset of kernel mappings. 0000'0000'0000'00000 0000'7fff'ffff'ffff128 TB=247user-space virtual memory, different per mm ffff'ffff'ffe0'0000 -2 MB ffff'ffff'ffff'ffff 2 MB=221... unused hole ffff'ffff'ff60'0000 -10 MB ffff'ffff'ff60'0fff 4 kB=212 VSYSCALL_ADDR - legacy vsyscall ABI ffff'ffff'8000'0000 -2 GB ffff'ffff'9fff'ffff 512 MB=229 kernel text mapping, mapped to physical address 0 ffff'8880'0000'0000 -119.5 TB ffff'c87f'ffff'ffff 64 TB page_offset_base = __PAGE_OFFSET_BASE_L4 - direct mapping of all physical memory ffff'8000'0000'0000 -128 TB ffff'87ff'ffff'ffff 8 TB ... guard hole, also reserved for hypervisor border|center|x86-64 memory layout ⚲ API: 8 setarch --addr-no-randomize cat /proc/self/maps ⚙️ Internals: arch/x86/include/asm/page_64_types.h – x86-64 page type definitions arch/x86/mm/init_64.c – x86-64 memory initialization 📚 References: X86_64 memory map x86/x86_64/mm.html Address_space_layout_randomization#Linux Address space layout randomization Pages In Linux, different architectures have different page sizes. The original —for x86 architecture— and still most commonly used page size is 4096 bytes (4 KB). The page size (in bytes) of the current architecture is defined by the PAGE_SIZE macro included in arch/x86/include/asm/page_types.h header file. User space programs can get this value using the 2 getpagesize library function. Another related macro is PAGE_SHIFT, that contains the number of bits to shift an address to get its page number —12 bits for 4K pages. One of the most fundamental kernel data structures relating memory-management is struct page. The kernel keeps track of the status of every page of physical memory present in the system using variables of this type. There are millions of pages in a modern system, and therefore there are millions of these structures in memory. The full definition of struct page can be found in linux/mm_types.h. ⚙️ Internals: mm/memory.c – page fault handling and page table operations (handle_mm_fault) linux/rmap.h, mm/rmap.c – reverse mapping, virtual-to-physical tracking for page reclaim linux/compaction.h, mm/compaction.c – memory compaction, reduces fragmentation linux/memblock.h, mm/memblock.c – early boot memory allocator, before buddy is available linux/highmem.h – page content access and manipulation asm-generic/tlb.h, mm/mmu_gather.c – TLB flush and page table teardown batching Pages NUMA In Non-uniform memory access systems, physical memory is divided into nodes, each local to a group of CPUs. Accessing local memory is faster than remote memory, so the kernel tries to allocate memory from the node closest to the requesting CPU. Each node contains its own set of zones (DMA, Normal, etc.). ⚲ API: 8 numactl – controls NUMA policy for processes or shared memory 8 numastat – per-node memory statistics (hits, misses, foreign allocations) /sys/devices/system/node/node*/meminfo – per-node memory info /sys/devices/system/node/node*/cpulist – CPUs belonging to each node /sys/devices/system/node/node*/distance – inter-node distances 2 set_mempolicy – set default NUMA memory policy 2 mbind – set NUMA memory policy for a memory range 2 get_mempolicy 2 migrate_pages 2 move_pages cat /proc/buddyinfo /sys/devices/system/node/ linux/topology.h – cpu_to_node, numa_node_id linux/mempolicy.h ⚙️ Internals: CONFIG_NUMA pglist_data (pg_data_t) – per-node memory descriptor, contains zones @ linux/mmzone.h numa_node_id – returns NUMA node of current CPU mm/numa.c – NUMA node data allocation during boot mm/mempolicy.c – NUMA memory allocation policies mm/migrate.c – page migration between nodes mm/memory-tiers.c – memory tiering (DRAM, PMEM, HBM) mm/numa_memblks.c – memory block and distance setup 📚 References: NUMA Memory Policy admin-guide/mm/numa_memory_policy.html Non-uniform memory access See also SMP section for NUMA topology and CPU aspects 🔨 stress-ng --numa Huge pages Huge pages use larger page sizes (2 MB or 1 GB on x86-64) to reduce TLB misses and page table overhead for memory-intensive workloads. HugeTLB HugeTLB provides explicitly allocated persistent huge pages, reserved at boot or runtime. ⚲ API: cat /proc/meminfo | grep Huge cat /proc/sys/vm/nr_hugepages 2 mmap with MAP_HUGETLB mount -t hugetlbfs nodev /dev/hugepages linux/hugetlb.h ⚙️ Internals: mm/hugetlb.c – HugeTLB huge page allocator hugetlb_init hugetlb_fault 📚 References: HugeTLB Pages admin-guide/mm/hugetlbpage.html Transparent Huge Pages THP automatically promotes regular pages to huge pages without application changes (since 2.6.38). ⚲ API: cat /sys/kernel/mm/transparent_hugepage/enabled 2 madvise with MADV_HUGEPAGE linux/huge_mm.h ⚙️ Internals: mm/huge_memory.c – transparent huge page support khugepaged – daemon that collapses pages into huge pages mm/khugepaged.c – THP collapse daemon 📚 References: Transparent Hugepage Support admin-guide/mm/transhuge.html Concepts overview admin-guide/mm/concepts.html TLB Translation lookaside buffer is a hardware cache of virtual-to-physical address translations. The kernel must flush TLB entries when page table mappings change. On SMP, this requires Inter-processor interrupt IPIs to other CPUs (TLB shootdowns), which can impact real-time latency on isolated CPUs. ⚲ API asm-generic/tlb.h – generic TLB flush batching flush_tlb_all – flush entire TLB on all CPUs via IPI (TLB shootdown) __flush_tlb_all – local CPU only, no IPI, calls __flush_tlb_global flush_tlb_mm – flush TLB for a specific address space flush_tlb_page – flush single page from TLB flush_tlb_range – flush a range of user pages for a VMA flush_tlb_kernel_range – flush kernel mappings on all CPUs /sys/kernel/debug/tracing/events/tlb/tlb_flush/ ⚙️ Internals arch/x86/mm/tlb.c – x86 TLB flush implementation mm/mmu_gather.c – TLB flush batching 📖 References TLB arch/x86/tlb.html Cache and TLB Flushing Under Linux core-api/cachetlb.html CMA The Contiguous Memory Allocator (CMA) reserves a region of memory at boot for large physically contiguous allocations needed by DMA devices, GPUs and multimedia hardware (since 3.5). Unused CMA memory is available to the page allocator for movable pages. ⚲ API: cat /proc/meminfo | grep Cma linux/cma.h dma_alloc_contiguous CONFIG_CMA ⚙️ Internals: mm/cma.c – contiguous memory allocator core kernel/dma/contiguous.c – DMA-CMA integration mm/cma_debug.c – debugfs interface cma_alloc cma_release 📚 References: Contiguous Memory Allocator mm/cma.html DMA ⚲ API: dma_addr_t - bus address linux/dma-mapping.h rust/kernel/dma.rs – Rust bindings dma_alloc_coherent dma_alloc_pages pin_user_pages dma_map_single dma_data_direction dma_map_sg scatterlist dma_set_mask dma_set_coherent_mask dma_set_mask_and_coherent dma_sync_single_for_cpu dma_sync_single_for_device linux/gfp.h linux/dmapool.h dma_pool_create DMA-able memory: __get_free_page kmalloc kmem_cache_alloc get_user_pages pins user pages in memory, 👁 Examples: samples/kfifo/dma-example.c e1000_alloc_rx_buffers, e1000_alloc_ring_dma ⚙️ Internals: kernel/dma – DMA subsystem core mm/dmapool.c – small DMA-coherent allocations mm/gup.c – get/pin user pages kernel/dma/mapping.c – arch-independent DMA mapping 📚 References: Dynamic DMA mapping Guide core-api/dma-api-howto.html Dynamic DMA mapping using the generic device core-api/dma-api.html pin_user_pages() and related calls core-api/pin_user_pages.html LWM: get_user_pages, pinned pages, and DAX LKMPG: DMA and mmap 💾 Historical: LDD3:Memory Mapping and DMA http://www.xml.com/ldd/chapter/book/ch13.html mmap and DMA SAC – Single Address Cycle, 32-bit DMA addressing (up to 4 GB) DAC – Dual Address Cycle, 64-bit DMA addressing DMAEngine linux/dmaengine.h drivers/dma – DMA engine drivers driver-api/dmaengine https://bootlin.com/pub/conferences/2015/elc/ripard-dmaengine/ ... 📚 References for the article: Linux Memory Management Documentation mm/ Analysis of Linux Memory Management Mechanism Memory management http://linux-mm.org/LinuxMM http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO-7.html Memory management, lwn