kernel/cgroup Cgroup 机制与原理详解

kernel/cgroup Cgroup 机制与原理详解

源码路径rk3588/kernel-6.1/kernel/cgroup/
内核版本:Linux 6.1(RK3588 平台)
平台:RK3588(4×Cortex-A76 + 4×Cortex-A55 big.LITTLE)

该目录实现 Linux cgroup(Control Group) 子系统的核心框架及部分内置控制器。Cgroup 将进程组织成层次化分组,对 CPU、内存、I/O、设备等资源进行限制、隔离与统计,是容器(Docker/LXC)、systemd、Android 资源管控的基础。

说明:cgroup 采用插件化设计。本目录提供统一框架(层级管理、任务迁移、kernfs 接口、统计等),各资源控制器分散在内核其他目录实现,通过 cgroup_subsys 注册接入。


目录


一、源码目录结构

1.1 编译单元(Makefile)

1
2
3
4
5
6
7
8
obj-y := cgroup.o rstat.o namespace.o cgroup-v1.o freezer.o

obj-$(CONFIG_CGROUP_FREEZER) += legacy_freezer.o
obj-$(CONFIG_CGROUP_PIDS) += pids.o
obj-$(CONFIG_CGROUP_RDMA) += rdma.o
obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_CGROUP_MISC) += misc.o
obj-$(CONFIG_CGROUP_DEBUG) += debug.o
编译单元 源文件 规模 功能
核心框架 cgroup.c ~7,083 行 层级管理、css/css_set、迁移、kernfs、挂载
Cpuset cpuset.c ~4,246 行 CPU/内存节点亲和性与隔离
Cgroup v1 cgroup-v1.c ~1,308 行 v1 挂载、release agent、pidlist
递归统计 rstat.c ~549 行 可扩展 per-CPU 递归资源统计
RDMA rdma.c ~610 行 RDMA 资源限制
Misc misc.c ~424 行 杂项资源(如 AMD SEV ASID)
Pids pids.c ~387 行 进程数限制
Debug debug.c ~381 行 调试控制器
Legacy Freezer legacy_freezer.c ~487 行 v1 freezer 控制器
Freezer freezer.c ~323 行 v2 cgroup 冻结
Namespace namespace.c ~151 行 cgroup 命名空间
内部头文件 cgroup-internal.h ~299 行 框架内部类型与 API

1.2 子系统清单(cgroup_subsys.h)

所有控制器在 include/linux/cgroup_subsys.h 中枚举:

子系统 实现位置 功能
cpuset kernel/cgroup/cpuset.c CPU/内存节点绑定
cpu kernel/sched/core.c CFS 带宽/权重控制
cpuacct kernel/sched/cpuacct.c CPU 使用时间统计
io block/blk-cgroup.c 块 I/O 带宽/权重
memory mm/memcontrol.c 内存限制与回收
devices security/device_cgroup.c 设备访问控制
freezer kernel/cgroup/freezer.c 进程冻结(v2)
net_cls net/core/ 网络 classid 标记
perf_event kernel/events/core.c perf 事件限制
net_prio net/core/ 网络优先级
hugetlb mm/hugetlb_cgroup.c 大页内存限制
pids kernel/cgroup/pids.c 进程数限制
rdma kernel/cgroup/rdma.c RDMA 资源限制
misc kernel/cgroup/misc.c 杂项硬件资源
debug kernel/cgroup/debug.c 调试接口

二、整体架构

2.1 分层模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────────────────────────────────────────────────┐
│ 用户空间 │
│ systemd / Docker / crictl / echo > cgroup.procs │
└──────────────────────────┬──────────────────────────────────┘
│ 读写 /sys/fs/cgroup/ (kernfs)
┌──────────────────────────▼──────────────────────────────────┐
│ cgroup.c + cgroup-v1.c (核心框架) │
│ cgroup_root │ cgroup │ css_set │ 迁移 │ 挂载 │ 文件接口 │
└──────┬──────────┬──────────┬──────────┬─────────────────────┘
│ │ │ │
┌──────▼──┐ ┌─────▼────┐ ┌──▼──────┐ ┌─▼──────────────┐
│ cpuset │ │ cpu/mem │ │ freezer │ │ pids/rdma/ │
│ (本目录) │ │ (sched/mm)│ │ (本目录)│ │ misc (本目录)│
└──────┬──┘ └─────┬────┘ └──┬──────┘ └─┬──────────────┘
│ │ │ │
└──────────┴──────────┴──────────┘

┌────────────▼────────────┐
│ task_struct │
│ task->cgroups (css_set)│
│ fork/exit 钩子 │
└─────────────────────────┘

2.2 关键锁

1
2
3
4
// cgroup.c
DEFINE_MUTEX(cgroup_mutex); // 层级结构修改主锁
DEFINE_SPINLOCK(css_set_lock); // task->cgroups、css_set 链表
DEFINE_PERCPU_RWSEM(cgroup_threadgroup_rwsem); // 线程组迁移
保护对象
cgroup_mutex cgroup 树创建/销毁、控制器 enable/disable、迁移准备
css_set_lock task->cgroups 指针、css_set 哈希表、任务链表
cgroup_threadgroup_rwsem 线程组级 attach 操作

2.3 默认层级

1
2
3
// cgroup.c
struct cgroup_root cgrp_dfl_root; // unified v2 默认层级
LIST_HEAD(cgroup_roots); // 所有层级根(含 v1 多层级)
  • cgroup v2(default hierarchy):单一统一层级,挂载于 /sys/fs/cgroup
  • cgroup v1(legacy):可多层级,每层级绑定不同控制器组合

三、核心数据结构

3.1 struct cgroup — 控制组节点

1
2
3
4
5
6
7
8
9
10
11
12
13
// include/linux/cgroup-defs.h
struct cgroup {
struct cgroup_subsys_state self; // 自身 css(ss == NULL)
unsigned long flags; // CGRP_FREEZE, CGRP_FROZEN 等
int level; // 树深度(root = 0)
struct kernfs_node *kn; // kernfs 目录节点
struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
u16 subtree_control; // 子 cgroup 启用的控制器
u16 subtree_ss_mask; // 实际生效的控制器掩码
struct cgroup_root *root;
struct cgroup *dom_cgrp; // 域 cgroup(threaded 模式)
// ...
};

每个 cgroup 在文件系统中对应一个目录(如 /sys/fs/cgroup/system.slice/)。

3.2 struct cgroup_subsys_state (css) — 控制器状态

1
2
3
4
5
6
7
8
9
10
11
struct cgroup_subsys_state {
struct cgroup *cgroup; // 所属 cgroup
struct cgroup_subsys *ss; // 所属子系统
struct percpu_ref refcnt; // 引用计数
struct list_head sibling; // 兄弟 css 链表
struct list_head children; // 子 css 链表
struct cgroup_subsys_state *parent;
int id; // 子系统内唯一 ID
u64 serial_nr; // 全局递增序号
// ...
};

每个 (cgroup, subsystem) 对一个 css 实例。例如启用 memory 控制器的 cgroup 有 memory css。

3.3 struct css_set — 任务 cgroup 成员关系

1
2
3
4
5
6
7
8
9
struct css_set {
struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; // 各子系统 css 指针
refcount_t refcount;
struct css_set *dom_cset; // 域 css_set(threaded 模式)
struct cgroup *dfl_cgrp; // 默认层级 cgroup
struct list_head tasks; // 属于此 cset 的任务链表
struct list_head cgrp_links; // 与 cgroup 的 M:N 关联
// ...
};

设计要点:一个任务的 task->cgroups 指向一个 css_set。多个任务可共享同一 css_set(当它们在所有层级上的 cgroup 成员关系完全相同时),fork 时只需增减 css_set 引用计数,避免逐控制器更新。

3.4 struct cgroup_root — 层级根

1
2
3
4
5
6
7
8
9
struct cgroup_root {
struct kernfs_root *kf_root; // kernfs 根
struct cgroup cgrp; // 根 cgroup
int hierarchy_id;
u16 subsys_mask; // v1: 挂载的控制器掩码
unsigned int flags; // CGRP_ROOT_* 标志
char release_agent_path[PATH_MAX]; // v1 release agent
// ...
};

3.5 struct cgroup_subsys — 控制器插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct cgroup_subsys {
struct cgroup_subsys_state *(*css_alloc)(struct cgroup_subsys_state *parent_css);
int (*css_online)(struct cgroup_subsys_state *css);
void (*css_offline)(struct cgroup_subsys_state *css);
void (*css_free)(struct cgroup_subsys_state *css);
int (*can_attach)(struct cgroup_taskset *tset);
void (*attach)(struct cgroup_taskset *tset);
void (*fork)(struct task_struct *task);
void (*exit)(struct task_struct *task);
struct cftype *dfl_cftypes; // v2 接口文件
struct cftype *legacy_cftypes; // v1 接口文件
const char *name;
bool implicit_on_dfl; // v2 隐式启用
bool threaded; // 支持 threaded 模式
// ...
};
1
2
3
cgroup A ←── cgrp_cset_link ──→ css_set X ←── task 1, task 2
cgroup B ←── cgrp_cset_link ──→ css_set X
cgroup C ←── cgrp_cset_link ──→ css_set Y ←── task 3

一个 css_set 可关联多个 cgroup(v1 多层级),一个 cgroup 也可关联多个 css_set(不同任务组合)。


四、Cgroup v1 与 v2

4.1 对比

特性 cgroup v1 cgroup v2(Unified)
层级数量 多个独立层级 单一统一层级
控制器绑定 挂载时绑定到层级 通过 cgroup.subtree_control 按需启用
进程规则 父子可同时有进程 默认 domain 模式:非 root 内部不能有进程
接口路径 每控制器独立文件 统一 cgroup.* 接口
挂载点 /sys/fs/cgroup/<controller> /sys/fs/cgroup
文件系统 cgroup cgroup2
Freezer legacy_freezer(独立控制器) 内置 cgroup.freeze

4.2 v2 Domain 与 Threaded 模式

  • Domain cgroup:资源隔离边界,可启用所有控制器,内部不应直接持有进程(leaf 除外)
  • Threaded cgroup:仅支持 cpumemorypidsperf_event 等 threaded 控制器,用于线程级分组

通过 cgroup.type 文件设置:domaindomain threadedthreaded

4.3 v2 控制器启用流程

1
2
3
4
5
6
# 在父 cgroup 启用 memory 和 cpu 控制器供子 cgroup 使用
echo "+memory +cpu" > /sys/fs/cgroup/cgroup.subtree_control

# 在子 cgroup 中设置限制
echo "max 200000" > /sys/fs/cgroup/mygroup/cpu.max
echo "256M" > /sys/fs/cgroup/mygroup/memory.max

五、子系统注册与生命周期

5.1 注册机制

1
2
3
4
// cgroup.c — 编译期生成子系统指针数组
struct cgroup_subsys *cgroup_subsys[] = {
#include <linux/cgroup_subsys.h> // SUBSYS(cpu) → &cpu_cgrp_subsys
};

每个控制器在各自源文件中定义:

1
2
3
4
5
6
7
8
9
10
11
12
// kernel/sched/core.c
struct cgroup_subsys cpu_cgrp_subsys = {
.css_alloc = cpu_css_alloc,
.css_online = cpu_css_online,
.css_offline = cpu_css_offline,
.css_free = cpu_css_free,
.can_attach = cpu_cgroup_can_attach,
.attach = cpu_cgroup_attach,
.fork = cpu_cgroup_fork,
.dfl_cftypes = cpu_files,
.name = "cpu",
};

5.2 css 生命周期

1
2
3
4
5
6
7
8
9
cgroup 创建子目录
→ css_alloc(parent_css) // 分配子 css
→ css_online(css) // 激活,CSS_ONLINE 置位
→ 用户写入接口文件配置限制

cgroup 删除(rmdir)
→ css_offline(css) // 停用,拒绝新任务
→ css_released(css) // 引用归零
→ css_free(css) // 释放(可能异步 via workqueue)

5.3 任务生命周期钩子

1
2
3
4
5
6
7
// include/linux/cgroup.h
void cgroup_fork(struct task_struct *p); // fork 时继承 css_set
int cgroup_can_fork(...); // fork 前检查(pids 等)
void cgroup_post_fork(...); // fork 后通知控制器
void cgroup_exit(struct task_struct *p); // 退出时递减计数
void cgroup_release(struct task_struct *p);
void cgroup_free(struct task_struct *p);

六、任务迁移机制

6.1 迁移 API

1
2
3
// 用户写入 cgroup.procs 或 cgroup.threads 触发
int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader,
bool threadgroup);

6.2 迁移流程

1
2
3
4
5
6
7
8
9
10
cgroup_attach_task()
├── cgroup_migrate_add_src() // 收集源 css_set
├── cgroup_migrate_prepare_dst() // 预创建/查找目标 css_set
└── cgroup_migrate()
├── cgroup_migrate_add_task() // 任务加入 mg_tasks 链表
└── cgroup_migrate_execute()
├── can_attach() // 各控制器预检查
├── css_set_move_task() // 切换 task->cgroups(commit)
├── attach() // 通知控制器迁移完成
└── post_attach()

核心 commit 点(cgroup_migrate_execute):

1
2
3
4
5
6
7
8
spin_lock_irq(&css_set_lock);
list_for_each_entry(cset, &tset->src_csets, mg_node) {
list_for_each_entry_safe(task, tmp_task, &cset->mg_tasks, cg_list) {
css_set_move_task(task, from_cset, to_cset, true);
cgroup_freezer_migrate_task(task, from_cset->dfl_cgrp, to_cset->dfl_cgrp);
}
}
spin_unlock_irq(&css_set_lock);

原子性保证:所有 can_attach() 通过后才会 commit;任一失败则全部回滚。

6.3 常用迁移方式

方式 接口 说明
写入 procs echo PID > cgroup.procs 迁移进程(thread group leader)
写入 threads echo PID > cgroup.threads 迁移单个线程
clone 直接加入 clone3(CLONE_INTO_CGROUP) 创建时直接进入目标 cgroup
批量迁移 cgroup.transfer_tasks v1 控制器间迁移

七、递归统计 rstat

7.1 设计目标

rstat.c 实现 可扩展递归统计(scalable recursive statistics)

  • 每个 cgroup 维护 per-CPU 统计(cgroup_rstat_cpu
  • 写入时仅标记本 cgroup 为 “updated”
  • 读取时惰性向上传播到祖先,复杂度 O(活跃子树大小) 而非 O(总子树)

7.2 数据结构

1
2
3
4
5
6
7
struct cgroup_rstat_cpu {
struct u64_stats_sync bsync;
struct cgroup_base_stat bstat; // CPU 时间等基础统计
struct cgroup_base_stat last_bstat; // 上次读取快照
struct cgroup *updated_children; // 有更新的子 cgroup 链表
struct cgroup *updated_next;
};

7.3 使用场景

  • cgroup.stat — 显示 CPU 使用统计
  • memory.currentmemory.peak 等(memory 控制器扩展 rstat)
  • PSI(Pressure Stall Information)压力指标

八、本目录内置控制器

8.1 Cpuset(cpuset.c)

最复杂的内置控制器(~4,246 行),管理 CPU 和内存节点亲和性:

接口文件 功能
cpuset.cpus 允许使用的 CPU 集合
cpuset.mems 允许使用的内存节点
cpuset.cpu_exclusive CPU 独占
cpuset.mem_exclusive 内存节点独占
cpuset.cpus.effective 有效 CPU(考虑父级约束)

RK3588 big.LITTLE 场景下,cpuset 可将任务绑定到 A76 或 A55 核心簇。

8.2 Freezer(freezer.c + legacy_freezer.c)

v2 freezerfreezer.c):

接口 功能
cgroup.freeze 写 1 冻结 cgroup 内所有任务
cgroup.events 读取 frozen 状态

冻结机制:设置 CGRP_FREEZE 标志,对任务发送 SIGSTOP,CGRP_FROZEN 表示实际已冻结。支持递归:所有子 cgroup 都 frozen 时父 cgroup 也标记 frozen。

v1 legacy_freezerlegacy_freezer.c):独立的 freezer 控制器,freezer.state 文件。

8.3 Pids(pids.c)

限制 cgroup 内进程数量:

接口 功能
pids.max 最大进程数(”max” = 无限制)
pids.current 当前进程数
pids.events 超限事件计数

fork() 时通过 can_fork() 检查,超限返回 -EAGAIN

8.4 RDMA(rdma.c)

限制 RDMA 资源使用:

资源 说明
hca_handle HCA 句柄数
hca_object HCA 对象数

按 cgroup × RDMA 设备维护 resource pool。

8.5 Misc(misc.c)

杂项硬件资源限制(如 AMD SEV/SEV-ES ASID 数量),采用 Limits 分配模型。

8.6 Debug(debug.c)

调试控制器,仅在 cgroup_debug=1 时启用,提供额外诊断接口。


九、分散实现的控制器

9.1 CPU 控制器(kernel/sched/core.c)

接口 功能
cpu.max CFS 带宽上限(v2)
cpu.weight 相对权重(默认 100)
cpu.stat usage、user、system 等
cpu.pressure CPU PSI 压力

与 CFS 调度器深度集成,通过 task_group 实现带宽控制。

9.2 Memory 控制器(mm/memcontrol.c)

接口 功能
memory.max 内存硬上限
memory.high 内存软上限(触发 reclaim)
memory.current 当前使用量
memory.swap.max swap 上限
memory.events oom、max 等事件
memory.stat 详细内存统计

通过 mem_cgroup 结构跟踪 page cache、anon、swap 等。

9.3 IO 控制器(block/blk-cgroup.c)

接口 功能
io.max 设备级 I/O 带宽/IOPS 上限
io.weight 相对 I/O 权重
io.stat 读写统计
io.pressure I/O PSI 压力

9.4 其他

控制器 位置 功能
cpuacct kernel/sched/cpuacct.c CPU 时间记账(v1 为主)
devices security/device_cgroup.c 字符/块设备访问 whitelist
net_cls net/core/ 设置 sk->classid
net_prio net/core/ 设置 socket 优先级
hugetlb mm/hugetlb_cgroup.c 大页内存限制
perf_event kernel/events/core.c perf 事件作用域

十、Cgroup Namespace

namespace.c 实现 cgroup namespace(CLONE_NEWCGROUP):

1
2
3
4
5
struct cgroup_namespace {
struct ns_common ns;
struct user_namespace *user_ns;
struct css_set *root_cset; // 命名空间内的"根" css_set
};
  • 容器内 /proc/self/cgroup 显示相对于 namespace root 的路径
  • 创建需要 CAP_SYS_ADMIN
  • 与 mount namespace 配合实现容器 cgroup 视图隔离

十一、用户空间接口

11.1 v2 统一接口(每个 cgroup 目录)

文件 功能
cgroup.procs 读写:迁移进程
cgroup.threads 读写:迁移线程
cgroup.controllers 只读:可用控制器
cgroup.subtree_control 读写:子 cgroup 启用的控制器
cgroup.type domain / threaded 类型
cgroup.max.depth 最大子 cgroup 深度
cgroup.max.descendants 最大子 cgroup 数量
cgroup.stat CPU 使用统计
cgroup.freeze 冻结/解冻
cgroup.events frozen、populated 等事件
cpu.max / memory.max / … 各控制器限制

11.2 常用操作示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建 cgroup 并设置内存限制
mkdir /sys/fs/cgroup/myapp
echo "+memory +cpu" > /sys/fs/cgroup/cgroup.subtree_control
echo "256M" > /sys/fs/cgroup/myapp/memory.max
echo "50000 100000" > /sys/fs/cgroup/myapp/cpu.max # 50ms/100ms = 50% CPU
echo $$ > /sys/fs/cgroup/myapp/cgroup.procs

# 查看 cgroup 路径
cat /proc/self/cgroup

# 冻结 cgroup
echo 1 > /sys/fs/cgroup/myapp/cgroup.freeze

# cpuset 绑定到 CPU 4-7(A76 大核)
echo "4-7" > /sys/fs/cgroup/myapp/cpuset.cpus
echo 0 > /sys/fs/cgroup/myapp/cpuset.mems
echo $$ > /sys/fs/cgroup/myapp/cgroup.procs

11.3 bpffs 与 cgroup BPF

cgroup BPF 程序(kernel/bpf/cgroup.c)可附加到 cgroup 的多种 hook 点(ingress/egress/bind/connect 等),实现网络策略。挂载通过 BPF_LINK_CREATE 或 cgroup 目录下的 BPF 接口。


十二、完整任务加入 Cgroup 时序

v2 写入 cgroup.procs 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[用户空间]
echo 1234 > /sys/fs/cgroup/mygroup/cgroup.procs

[内核 - VFS/kernfs]
cgroup_procs_write()
→ cgroup_attach_task(mygroup, task, true)

[内核 - 迁移准备]
cgroup_migrate_add_src(task_css_set(task), mygroup, &mgctx)
cgroup_migrate_prepare_dst(&mgctx)
→ 查找或创建目标 css_set

[内核 - 预检查]
cgroup_migrate_execute(&mgctx)
→ memory_can_attach() // 检查 memory 限制
→ cpu_can_attach() // 检查 cpu 约束
→ pids_can_attach() // 检查 pids 限制
→ cpuset_can_attach() // 检查 CPU 亲和性

[内核 - Commit]
→ css_set_move_task(task, from, to, true)
→ task->cgroups = to_cset
→ cgroup_freezer_migrate_task() // 处理 freeze 状态

[内核 - 通知控制器]
→ memory_attach() // 更新 memcg 计数
→ cpu_attach() // 更新 task_group
→ cpuset_attach() // 更新 CPU 亲和性 mask

[内核 - 调度影响]
下次 schedule() 时 task 在新 cgroup 的 CPU 权重/带宽下运行
内存分配计入新 memcg

十三、RK3588 / Android 平台应用

13.1 典型 cgroup 层级(Android/systemd)

1
2
3
4
5
6
7
/sys/fs/cgroup/
├── init.scope
├── system.slice/
│ ├── docker.service/
│ └── ...
├── user.slice/
└── ...

Android 使用 cgroup v2 管理应用进程资源(通过 libprocessgroup):

场景 使用的控制器
应用内存限制 memory.max
CPU 带宽控制 cpu.max
后台冻结 cgroup.freeze
核心绑定(游戏/性能模式) cpuset.cpus
进程数限制 pids.max

13.2 RK3588 big.LITTLE cpuset 配置

1
2
3
4
5
6
7
8
# 性能组:绑定 4 个 A76 大核 (CPU 4-7)
echo "4-7" > /sys/fs/cgroup/performance/cpuset.cpus

# 节能组:绑定 4 个 A55 小核 (CPU 0-3)
echo "0-3" > /sys/fs/cgroup/background/cpuset.cpus

# 查看有效 CPU
cat /sys/fs/cgroup/mygroup/cpuset.cpus.effective

13.3 调试命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看进程 cgroup  membership
cat /proc/<PID>/cgroup

# 查看 cgroup 内进程
cat /sys/fs/cgroup/<path>/cgroup.procs

# 查看内存使用
cat /sys/fs/cgroup/<path>/memory.current
cat /sys/fs/cgroup/<path>/memory.stat

# 查看 CPU 统计
cat /sys/fs/cgroup/<path>/cpu.stat

# 查看 PSI 压力
cat /sys/fs/cgroup/<path>/memory.pressure
cat /sys/fs/cgroup/<path>/cpu.pressure
cat /sys/fs/cgroup/<path>/io.pressure

13.4 确认配置

1
2
zcat /proc/config.gz | grep -E 'CGROUP|CPUSET|MEMCG|BLK_CGROUP'
mount | grep cgroup

RK3588 典型配置:

  • CONFIG_CGROUPS=y
  • CONFIG_CGROUP_V2=y(默认 unified hierarchy)
  • CONFIG_MEMCG=y
  • CONFIG_CGROUP_SCHED=y(cpu 控制器)
  • CONFIG_BLK_CGROUP=y(io 控制器)
  • CONFIG_CPUSETS=y

十四、总结

kernel/cgroup 是 Linux 资源管控的核心基础设施:

  1. 统一框架cgroup.c)— 层级管理、css_set 优化、任务迁移、kernfs 接口
  2. 插件化控制器 — 通过 cgroup_subsys 注册,分散在各子系统实现
  3. v2 Unified Hierarchy — 单一层级、按需启用控制器、domain/threaded 模式
  4. css_set 共享 — 相同 cgroup 组合的任务共享 css_set,优化 fork 性能
  5. 原子迁移 — can_attach → commit → attach 三阶段保证一致性
  6. rstat — 高效递归统计,支撑 cgroup.stat 和 PSI

在 RK3588 / Android 平台上,cgroup 是进程资源隔离与限制的基础,与调度器(cpu)、内存管理(memory)、块 I/O(io)深度协同,是容器化和系统资源管控的基石。


附录:源文件完整清单

文件 行数 分类
cgroup.c 7,083 核心框架
cpuset.c 4,246 Cpuset 控制器
cgroup-v1.c 1,308 v1 兼容
rdma.c 610 RDMA 控制器
rstat.c 549 递归统计
legacy_freezer.c 487 v1 Freezer
misc.c 424 Misc 控制器
pids.c 387 Pids 控制器
debug.c 381 Debug 控制器
freezer.c 323 v2 Freezer
cgroup-internal.h 299 内部头文件
namespace.c 151 Cgroup namespace

文章互动

阅读 --

留言

0 条留言

正在加载留言…