list_lru
[TOC] list_lru: Linux内核的可扩展对象缓存管理器list_lru 是 Linux 内核提供的一套可扩展的、近似 LRU (Least Recently Used) 缓存列表管理机制。它专门设计用来高效地管理大量、小型、生命周期不一的内核对象,例如目录项缓存(dentries)和索引节点缓存(inodes)。 可以将其想象成一个特殊的“图书馆卡片目录系统”,这个系统需要被许多图书管理员(CPU核心)同时、频繁地访问,并且需要一种高效的方式来找出那些最久未被使用的卡片(对象)以便回收。 一、 核心问题:为什么需要 list_lru?在理解 list_lru 的设计之前,必须先明白它要解决的核心问题:在多核环境下的锁竞争。 一个朴素的 LRU 列表实现通常是这样的: 维护一个全局的双向链表。 当一个对象被访问时,将它从链表中的当前位置移到链表头(表示最新使用)。 当需要回收内存时,从链表尾部(表示最久未使用)开始移除对象。 这种实现在单核系统上工作得很好。但在现代多核系统中,会产生一个巨大的性能瓶颈:所有 CPU 核心都必须竞争同一个全局锁来修改这个链表...
memblock
[TOC] mm/memblock.c: Linux内核的“拓荒时代”内存管理器mm/memblock.c 实现了一种极其早期的、简单的物理内存分配器,它在内核启动的“拓荒时代”——即在页分配器(伙伴系统)初始化之前——扮演着至关重要的角色。 可以将其想象成一个在建造正式仓库(伙伴系统)之前,用来管理建筑材料(物理内存)的临时账本和场地规划师。它的唯一使命是在最原始的环境下,为内核自身的初始化提供最基本的内存分配服务,并在完成使命后,将所有管理权平稳地移交给更高级的内存管理系统。 一、 核心问题:为什么需要 memblock?在内核启动的极早期(start_kernel 函数刚开始执行时),真正的内存管理子系统(如伙伴系统、Slab 分配器)还完全不存在。这些高级系统本身就需要分配内存来存放它们复杂的数据结构(如 mem_map 数组、kmem_cache 结构等)。这就产生了一个“先有鸡还是先有蛋”的问题: 为了初始化内存管理器,你需要分配内存。 但为了分配内存,你需要一个已初始化的内存管理器。 memblock 就是为了打破这个循环而存在的。它是一个极其简单的...
backing-dev
[toc] mm/backing-dev.c 回写管理(Writeback Management) 脏页回写的调速器与执行者历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了解决Linux内核中一个核心的性能与数据一致性难题:如何智能、高效地将内存中被修改过的数据(“脏页”,Dirty Pages)写回到持久化存储设备(“后备设备”,Backing Device)中。 在mm/backing-dev.c所代表的现代回写框架出现之前,Linux的脏页回写机制比较原始,存在诸多问题: 全局瓶颈:早期的pdflush机制使用一个全局的线程池来处理所有设备的回写任务。这意味着一个慢速设备(如USB 1.0 U盘)的回写任务,可能会长时间占用一个flusher线程,从而阻塞一个高速设备(如NVMe SSD)的回写,造成**队头阻塞(Head-of-line blocking)**问题。 缺乏精细控制:无法对单个设备设置不同的回写策略。所有设备共享一套全局的回写参数,这对于性能差异巨大的异构存储环境是极其低效的。 写操作延迟风暴(Latency Spikes):当系...
init
[TOC] Linux 内存模型之基石:FLATMEM 深度解析FLATMEM 是 Linux 内核中最基础、最常用,也是最高效的内存模型。正如其名,“平坦内存”模型假定系统的物理内存是一个单一、连续、不存在大间隙的地址空间。 一、 核心原理:mem_map 数组FLATMEM 模型的全部精髓都围绕着一个核心数据结构:一个巨大的、全局的 struct page 数组,通常被称为 mem_map。 什么是 struct page? 在 Linux 内核中,物理内存不是按字节管理的,而是按固定大小的块来管理的,这个块被称为页帧 (Page Frame)(通常是 4KB)。 内核为每一个物理页帧都分配了一个 struct page 描述符。这个结构体包含了该物理页帧的所有元数据,例如:它的引用计数、它是否是脏页、是否被锁定、属于哪个地址空间映射等。 mem_map 的作用 FLATMEM 模型在内核启动的极早期,会分配一个足够大的连续内存区域,用来存放一个 struct page 数组。这个数组的大小足以覆盖从物理地址 0(或某个起始偏移)到系统最大物理内存地址之间的所有页...
nommu
[TOC] mm/nommu.c NO-MMU内存管理(NO-MMU Memory Management) 适用于无内存管理单元的系统历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了让Linux操作系统能够运行在没有**内存管理单元(MMU)**的简单微控制器(MCU)和嵌入式处理器上。标准的Linux内核设计严重依赖MMU来实现以下核心功能: 虚拟内存:为每个进程提供独立的、巨大的、线性的虚拟地址空间。 内存保护:利用硬件机制防止一个进程访问另一个进程或内核的内存空间,保障系统稳定性和安全性。 内存映射与分页:实现写时复制(Copy-on-Write)、按需分页(Demand Paging)和交换(Swapping)等高级内存管理技术。 许多低成本、低功耗的嵌入式处理器(如ARM Cortex-M系列)为了节省芯片面积和功耗,并不包含MMU。mm/nommu.c 及其相关代码提供了一套替代的、简化的内存管理模型,使得功能强大的Linux内核能够在这种受限的硬件上运行,这通常被称为uClinux(Micro-Controller Linux)。 它的...
page-writeback
[TOC] mm/page-writeback.c 页面回写(Page Writeback) 数据持久化的核心机制历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了解决一个计算机体系结构中的根本性矛盾:内存(RAM)与持久性存储设备(如硬盘、SSD)之间巨大的性能差距。 性能缓冲:应用程序向文件写入数据时,如果每次写入都必须等待慢速的存储设备完成,那么整个系统的性能和响应速度将变得无法接受。页面回写机制利用高速的内存作为写回缓存(Write-back Cache),允许write()系统调用将数据写入内存(即 Page Cache)后立即返回,从而极大地提升了应用程序的写入性能和系统吞吐量。 数据持久化:内存中的数据是易失的,断电后会丢失。因此,必须有一个可靠的机制,将在内存中被修改过的数据(称为“脏页”,Dirty Page)在合适的时机写回到持久性存储设备上,确保数据的最终安全性。 I/O效率优化:该机制可以将多次小的、离散的写入操作在内存中合并成一次大的、连续的写入操作,然后再提交给存储设备。这种**I/O合并(I/O...
nsfs
[toc] fs/nsfs.c 命名空间文件系统(Namespace Filesystem) 内核命名空间的句柄化接口历史与背景这项技术是为了解决什么特定问题而诞生的?nsfs(Namespace Filesystem)是一个内核中的“伪文件系统”(Pseudo-filesystem),它的诞生是为了解决一个核心问题:如何让用户空间的进程能够安全、稳定地引用(Reference)和操纵内核中的命名空间(Namespace)对象。 在nsfs和其配套的setns(2)系统调用出现之前,进程与命名空间的交互是有限且单向的: 缺乏进入(Entering)机制:一个已经存在的进程,没有一个标准的方法可以“进入”到另一个已经存在的命名空间中。进程只能在创建时(通过clone())进入新的命名-空间,或者通过unshare()将自己与父进程的命名空间分离开来,进入一个新建的命名空间。 缺乏持久化(Persistence)机制:一个命名空间的生命周期通常与其内部的进程绑定。当一个命名空间中最后一个进程退出时,这个命名空间就会被销毁。这使得创建“空的”、可供将来使用的命名空间变得非常...
percpu
[TOC] mm/percpu.c Per-CPU Variables Management Per-CPU数据管理的核心实现历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了从根本上解决在多核(SMP)系统中并发访问共享数据所带来的性能瓶颈而诞生的。 锁争用(Lock Contention):在多核系统中,如果多个CPU核心频繁地更新同一个全局变量(例如,一个网络数据包统计计数器),它们必须使用锁(如自旋锁)来保护这个变量,以避免数据竞争。当核心数量增加时,对这个锁的争夺会变得非常激烈,导致CPU花费大量时间在等待锁上,而不是执行实际工作,从而严重限制了系统的扩展性。 缓存一致性开销(Cache Coherency Overhead):即使不使用锁(例如使用原子操作),也会有性能问题。当一个CPU核心修改了共享变量,它所在的缓存行(Cache Line)会被标记为“脏”(Modified)。根据缓存一致性协议(如MESI),其他CPU核心上该缓存行的副本必须被置为“无效”(Invalidated)。当其他CPU也想访问这个变量时,就必须从修改过的那个核...
page_alloc
[TOC] mm/page_alloc.c 伙伴系统内存分配器(Buddy System Memory Allocator) 内核物理内存管理的核心历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了解决操作系统内核中最根本的问题之一:如何高效、可靠地管理整个系统的物理内存(RAM)。内核自身及其服务的子系统(如进程管理、文件系统缓存、网络协议栈)都需要动态地申请和释放内存。mm/page_alloc.c 中实现的伙伴系统(Buddy System)旨在满足以下核心需求: 管理基本单位:将物理内存划分为固定大小的“页”(通常是4KB),并以此为基本单位进行管理。 提供连续内存:许多硬件设备(特别是进行直接内存访问DMA的设备)和某些内核数据结构要求得到的内存块在物理上是连续的。伙伴系统的设计目标之一就是能够分配不同大小的、物理连续的内存块。 对抗外部碎片:在长时间运行的系统中,频繁地分配和释放不同大小的内存块会导致物理内存中产生许多不连续的小空闲块。这种现象称为“外部碎片”,它会导致即使总的空闲内存很多,也无法满足一个较大连续内存的申请。伙伴系统通过其独特...
swap
[TOC] mm/swap.c 交换机制(Swap Mechanism) 物理内存的虚拟扩展历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术以及其实现的交换(Swap)机制,是为了解决一个自计算机诞生以来就存在的根本性限制:物理内存(RAM)的大小是有限的。 运行大于物理内存的程序:在早期,如果一个程序需要比机器拥有的RAM更多的内存,它根本无法运行。交换机制通过将内存中不常用的部分临时存放到磁盘上,从而“欺骗”程序,让它以为自己拥有一个远大于实际物理内存的地址空间。这使得运行大型应用程序成为可能。 同时运行更多的程序:即使每个程序都能装入内存,但同时运行多个程序可能会迅速耗尽RAM。交换机制允许内核将处于空闲或等待状态的进程的内存换出到磁盘,从而为当前活动的进程腾出宝贵的物理内存,提高系统的并发能力和整体吞吐量。 系统休眠(Hibernation):为了实现休眠到磁盘(Suspend-to-Disk)功能,内核需要一个地方来存储整个系统内存的快照。交换空间(Swap Space)被自然地用作这个存储区域。 它的发展经历了哪些重要的里程碑或版本迭代?...








