SLUB 的类三级缓存结构

前言 本文基于 6.1 版本的 Linux 内核代码,阐述笔者对 SLUB 分配器原理的个人理解。本文的分析忽略以下内容: 所有 debug 相关特性(如 KASAN) 所有安全增强特性(如 CONFIG_SLAB_FREELIST_HARDENED) SLUB per-cpu partial cache 特性(CONFIG_SLUB_CPU_PARTIAL=n) 换言之,本文只关注最底层最基础的 SLUB 运行逻辑——一种类三级缓存的结构。该想法是在上班通勤途中阅读此文 获得的启发,遂希望通过阅读代码和画图整理,将之梳理清楚。 概述 一级缓存:per-cpu SLAB cache 代表结构:struct …

用于内核测试的内核模块

背景 在调试内核时,最常用的方式就是添加打印。这个方法简单直接,但有个问题:若添加打印的函数会被频繁地调用执行,那这很可能使系统在启动或运行阶段触发海量的打印,反而将关键的信息淹没;或者由此导致系统运行卡顿甚至无法启动。 还有另一种常见的调试需求:我们需要在内核中模拟某种故障,并且是以我们所能掌控的时机和方式来触发。关于这点我们一般会想到内核故障注入,但其手段和所涉及的软件工具比较复杂,且其所能模拟的故障种类和故障位置一般是给定的,无法随意调整。 对于上述两个场景,我们其实可以用同一个方法解决:在内核中预埋一个“开关”,并在内核的用户态接口(如 proc 文件系统)上创建一个专门的接口来控制这个开关。对于第一个场景,我们可以将那些打 …

Spinlock 代码及故障模型分析

代码流程 spinlock 上锁的代码流程: 1# include/linux/spinlock.h 2spin_lock 3 raw_spin_lock 4 # ifdef CONFIG_INLINE_SPIN_LOCK 5 # include/linux/spinlock_api_smp.h 6 # else 7 # kernel/locking/spinlock.c 8 _raw_spin_lock 9 # include/linux/spinlock_api_smp.h 10 __raw_spin_lock 11 preempt_disable() 12 spin_acquire(...) 可见,上锁时 spinlock 是 …

Linux 脚本执行:由一个补丁分析说起

事情背景 补丁链接:a4ae32c71fe9 (“exec: Always set cap_ambient in cap_bprm_set_creds”) 补丁信息中提到,该补丁是为了确保 cap_bprm_set_creds() 每次都会设置 cap_ambient 变量。另外还提到了下述内容: … if there is a suid or sgid script with an interpreter that has neither the suid nor the sgid bits set the interpreter should be able to accept …

进程切换与抢占

进程切换 概念 进程切换,又称上下文切换,分为 自愿(voluntary)切换:进程本身无法继续运行 例如需要等待 IO 完成(TASK_UNINTERRUPTABLE),或等待某个资源或事件的就绪(TASK_INTERRUPTIBLE),或正在被 debug/trace(TASK_STOPPED/TASK_TRACED) 强制(involuntary)切换:进程还可以运行,但内核不让它运行了 例如进程时间片用尽,或有优先级更高的其他进程 又例如进程自己决定主动让出 CPU(注意:这不属于自愿切换,因为进程仍处于 TASK_RUNNING 状态) 用户态程序通过 sched_yield …