Linux hypervisor
Created|Updated|基础设施
|Word Count:125|Reading Time:1mins|Post Views:
hypervisor 可以被认为等于 virtual hardware。他们的出现,可以有效减少硬件服务器数量。
常见的 hypervisor 分成两类:
- 直接运行在硬件上的,基于内核的虚拟机。 OS as hypervisor。典型例子是 KVM。KVM 是被集成到 Linux 内核之中的完整虚拟化解决方案。
- 运行于另一个操作系统之上。典型的例子是 QEMU 和 WINE。
hypervisor的实现,总是要映射一些磁盘设备和网络设备的。
Author: magicliang
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles
2026-05-24
Huge Page:TLB 压力和页表开销
上一篇讲了 NUMA 如何让内存访问不再均匀。但即使在单 node 系统上,当工作集足够大时,另一类开销浮现:TLB miss 和页表自身的内存消耗。Huge page 通过增大映射粒度来同时缓解这两个问题。 核心问题可以压成一句话: huge page 用更大的映射粒度减少 TLB 和页表开销,但引入碎片、分配时机和回收复杂度作为代价。 问题从哪里来 标准页大小 4KB。一个 64GB 内存的机器有 1600 万个物理页。如果一个进程映射了 8GB 工作集,对应 200 万个 PTE。 TLB(Translation Lookaside Buffer)是 MMU 的地址翻译缓存。现代 CPU 的 L1 dTLB 通常只有 64-128 个条目,L2 sTLB 有 1024-2048 个条目。200 万个活跃页面对 2048 个 TLB 条目意味着 TLB 覆盖率不足 0.1%——绝大多数访问要走 page table walk。 page table walk 不是免费的。它需要 4-5 次内存访问(每级页表一次),即使有 page walk cache 辅助,在 TLB...
2025-05-17
Unix/Linux 系统的常见目录
一级目录 目录路径 缩写解释 / 全称 用途描述 常见子目录/示例 / Root 根目录,所有其他目录的起点 无 /bin Binaries 基础命令的二进制文件(所有用户必需) ls, cp, mv, cat /boot Boot 系统启动文件(内核、引导加载程序) vmlinuz-*(内核文件)、grub/(GRUB配置)、initramfs /dev Devices 设备文件(物理/虚拟设备接口) sda(磁盘)、tty(终端)、null(空设备)、random(随机数生成器) /etc Etcetera 系统级配置文件(全局配置) passwd(用户账户)、fstab(挂载表)、apt/(APT包管理器配置)、ssh/ /home Home 用户主目录(个人文件和数据) /home/alice(用户 Alice 的目录) /lib Libraries 基础共享库和内核模块(支持 /bin 和 /sbin) libc.so(C标准库)、modules/(内核模块) /media Media 可移动设备挂载点(自动挂载) usb/(U...
2026-05-23
反向映射:从物理页找回虚拟地址
上一篇把 folio 作为缓存与回收的管理单位。一旦讨论“回收”,立刻冒出一个问题:内核拿到一个准备回收的 folio,怎么知道哪些进程的页表还指着它?正向页表只能从虚拟地址走到物理页,反过来走不通。反向映射就是为这件事存在的。 核心问题可以压成一句话: 正向页表回答“这个地址翻译到哪一页”,反向映射回答“这一页被哪些地址空间映射”。 问题从哪里来 页表只解决一个方向:拿到一个虚拟地址,按 PGD→P4D→PUD→PMD→PTE 走下去,最终得到 PFN。这是 MMU 在用户态访问路径上需要的。 但内核在很多场景需要反方向:拿到一个物理页(或 folio),找到所有当前映射它的虚拟页和对应 PTE。典型场景包括: 回收一个 folio。释放前必须撤销所有指向它的 PTE,否则用户态访问会拿到已释放的物理页。 迁移一个 folio。把内容搬到新物理页之后,所有原指针都要改写到新 PFN。 COW 写入触发时。即使是 do_wp_page 的判断,也要确认有没有其他映射方共享同一物理页。 在大页拆分、NUMA balancing、kernel same-page mergin...
2026-05-23
匿名页和 COW:fork 为什么便宜,写入为什么变贵
上一篇把缺页异常拆成了 fault 分派的几条路径。do_anonymous_page 处理首次访问匿名页,do_wp_page 处理写保护异常。这两条路径是 Linux VM 里两种延迟行为的核心:匿名页延迟到首次访问才分配物理页,COW 延迟到首次写入才复制。 核心问题可以压成一句话: 匿名页是没有文件 backing 的内存承诺;COW 把页面复制成本推迟到第一次写入。 问题从哪里来 malloc(1GB) 在多数 Linux 系统上不会失败,也几乎不消耗物理内存。fork() 一个驻留几 GB 的进程,能在毫秒级返回,不会发生几 GB 的复制。这两件事在朴素的“内存就是数组、复制就是按字节抄”的模型里都讲不通。 把它们拆开后: malloc 返回的是用户态地址,背后通常是 brk 或匿名 mmap。这一步只是建立一段匿名 VMA,没有分配任何物理页面。第一次访问这段区间的某一页时,缺页异常走到 do_anonymous_page,从空闲页池里取一页、清零、填进 PTE。1GB 全分配但只访问 4KB 的程序,物理内存增长就只有 4KB。 fork 复制的是 mm_s...

2026-10-01
容器 E01:gVisor、Kata 和 microVM 改变了哪层边界
主线08指出 Linux namespace 与 seccomp 不能组合成一句“完全安全”。当隔离目标是降低对宿主内核系统调用面的直接依赖时,gVisor 与 Kata Containers 等项目提供不同的执行路径,但它们并非“给普通 runc 加同一个开关”。要先画清应用、系统调用实现、宿主内核或 guest kernel、硬件虚拟化的边界,再讨论兼容与成本。 隔离和兼容都需对象级比较 gVisor 项目文档把它描述成在应用与宿主内核间提供用户态内核接口/拦截路径;Kata 采用轻量 VM 方向的隔离,应用与 guest kernel 交互,宿主看到 VM 资源。实际 shim 与 runtime 组合依版本实现核对,microVM 是否具备硬件虚拟化支持也是实验前提。两者对特定系统调用、文件系统路径、网络 I/O 和启动资源的处理不同,不应拿一条“启动更慢”的口号当证据。 正常案例在独立 VM 上固定同一 probe-app 镜像 digest,分别用 runc、选定版本 gVisor 和 Kata 运行相同 /ready、/state 请求,记录系统调用兼容与资源边界;...
2026-05-24
SLUB:小对象为什么不直接按页分配
上一篇讲了 buddy allocator 如何按阶管理物理页的分配与释放。但 buddy 的最小粒度是一页(4KB)。内核中绝大多数对象远小于 4KB——一个 struct dentry 是 192 字节,一个 struct inode 是 600 字节左右。如果每个小对象都分配一整页,内部碎片率将高达 95% 以上。 核心问题可以压成一句话: 内核对象通常比一页小得多,SLUB 用 slab cache 把页切成同类型对象池,减少碎片和初始化成本。 问题从哪里来 内核不断创建和销毁各种数据结构:每次 open() 分配一个 struct file,每次路径查找分配一个 struct dentry,每次网络包到达分配一个 struct sk_buff。这些对象有两个共同特点: 第一,大小远小于 4KB。如果用 buddy allocator 直接分配,一个 192 字节的 dentry 占用 4096 字节物理页,利用率不到 5%。 第二,同类型对象的分配/释放极为频繁。dentry 在路径解析密集的工作负载中每秒创建/销毁数十万次。每次都调用 buddy allocat...
Announcement
人生只是,守株待兔






