cgroup子系统4_memory子系统

本文详细介绍了Linux cgroup中的memory子系统如何管理和限制进程的内存使用,包括内存分配、释放时的charge与uncharge机制,以及具体的操作点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

memory子系统设定cgroup中任务使用的内存限制,并自动生成那些任务使用的内存资源报告。memory子系统是通过

linux的resource counter机制实现的,在进程进行内存分配、释放时对进程进行charge、uncharge操作。


charge操作进行点:

1.分配新页框时(请求调页、copy on write),在do_falut,do_anonymous_page,do_wp_page中,通过mem_cgroup_newpage_charge。

2.处理页面换入时,在do_swap_page中,通过mem_cgroup_try_charge_swapin。

3.将page加入page cache时,在add_to_page_cache_locked中,通过mem_cgroup_cache_charge。

4.在处理内存迁移时,通过mem_cgroup_pre_migration。



uncharge操作进行点:

1.匿名页unmap时,通过mem_cgroup_uncharge_page

2.page cache删除页时,通过mem_cgroup_uncharge_page

3.swap cache删除页时,通过mem_cgroup_uncharge_swapcache

4.内存迁移时,通过mem_cgroup_end_migration

参考博客:

1.memory子系统

<think>嗯,用户想了解Linux内核cgroup_add_dfl_cftypes函数的作用和实现原理。用户似乎对cgroup机制有较深的研究兴趣,之前已经讨论过cgroup的初始化流程和数据结构关系,这次聚焦在具体接口函数上。 从用户提供的引用材料看,ta应该正在研究cgroup v2的文件系统交互层。引用[4]提到/sys/fs/cgroup目录结构与控制组的对应关系,这正是cftypes要解决的问题。用户可能正在编写自定义cgroup控制器,或者在做内核模块开发。 这个函数的核心价值在于动态扩展cgroup文件接口。需要重点解释清楚三个层面:功能定位(解决什么问题)、数据结构关联(cftype与cgroup_subsys的绑定)、运行时机制(文件操作如何触发控制组行为)。特别要注意区分v1和v2版本差异,引用[2]提到过版本判断逻辑。 用户可能隐含的需求是:如何在实际开发中运用这个接口?所以最后要给出典型应用场景。不过当前问题还是集中在原理层面,实现细节需要展示关键代码但不至于太底层。那些cgrp->root->cfts的链表操作可以简略描述,重点在cftype结构体的回调函数设计。 注意到用户贴的示例中有Python代码块,说明ta接受技术代码演示。但内核代码需要保持精简,只保留函数骨架和核心逻辑,避免include/defensive等次要内容。特别要标出cftypes数组定义这个关键输入参数。 安全方面要强调这个函数仅限内核模块使用,普通开发者应该通过cgroupfs接口操作。不过用户既然问到这个层级,应该是有内核开发背景的。</think>`cgroup_add_dfl_cftypes()` 是 Linux 内核中 Control Group (cgroup) 子系统用于**向 cgroup v2 层级注册默认控制文件**的核心函数。其作用与实现原理如下: --- ### **一、核心作用** 1. **注册控制文件 (cftypes)**: * 将一组预定义的控制文件接口(`struct cftype` 数组)添加到指定的 **cgroup v2 层级** (`struct cgroup_subsys` 或 `struct cgroup_root`)。 * 这些控制文件会出现在该层级下所有 cgroup 目录中(例如 `/sys/fs/cgroup/<controller>/<cgroup>/`),供用户空间读写以配置资源控制策略。 2. **区分 cgroup 版本**: * 函数名中的 `dfl` (default) 明确表示它**专用于 cgroup v2**(统一层级模式)。 * cgroup v1 使用类似但不同的接口(如 `cgroup_add_cftypes()` 或 `cgroup_add_legacy_cftypes()`)[^2]。 3. **扩展子系统功能**: * 允许 cgroup 子系统(如 `memory`, `cpu`, `io` 等)**动态添加**其实现资源控制所需的特定文件接口(如 `memory.max`, `cpu.weight`, `io.max` 等)。 --- ### **二、关键实现原理** 函数原型通常定义在 `kernel/cgroup/cgroup.c`: ```c int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); // 或 int cgroup_add_dfl_cftypes(struct cgroup_root *root, struct cftype *cfts); ``` 1. **参数解析**: * `ss` / `root`:指定目标 **cgroup v2 层级**。可以是具体的子系统指针 (`ss`) 或根层级指针 (`root`)。对于单控制器层级,两者通常关联。 * `cfts`:指向一个以 `{ }` 终止的 `struct cftype` 数组。每个元素定义一个控制文件: ```c struct cftype { char name[MAX_CFTYPE_NAME]; // 文件名 (e.g., "max") enum cftype_flags flags; // 文件属性 (RO, WO, RW, 原子写等) ssize_t (*read)(struct kernfs_open_file *of, ...); // 读回调 ssize_t (*write)(struct kernfs_open_file *of, ...); // 写回调 // ... 其他字段 (e.g., 私有数据, 序列化函数) }; ``` 2. **核心流程**: 1. **版本校验**:确保目标层级是 **cgroup v2** (`dfl`)。v1 层级调用此函数会失败。 2. **遍历 cfts 数组**:对数组中的每个 `struct cftype` 执行: * **绑定层级**:设置 `cft->ss = ss` 或关联到 `root`,标明文件所属子系统/层级。 * **注册到 kernfs**: * 调用 `cgroup_add_cftype()` 或类似内部函数。 * 该函数通过 `kernfs_create_file()` 在 **cgroup 的 kernfs 目录** 中创建实际的文件节点。 * 将 `cftype->read`/`write` 等回调函数**关联到 kernfs 文件操作**。 3. **链表管理**:将新注册的 `cftype` 添加到层级或子系统的 **cfts 链表** 中(如 `ss->cfts` 或 `root->cfts`),用于统一管理。 4. **错误回滚**:若中间步骤失败,回滚已创建的文件。 3. **运行时交互**: * 用户空间读写 `/sys/fs/cgroup/...` 下的文件时,内核的 **kernfs 子系统** 会调用该文件对应的 `cftype->read` 或 `cftype->write` 回调函数。 * 这些回调函数由**子系统实现**,负责: * `read`:从关联的 `cgroup` 数据结构中读取状态/配置值,格式化输出给用户。 * `write`:解析用户输入,验证并更新关联 `cgroup` 的控制参数,触发资源限制生效。 --- ### **三、典型使用场景 (在子系统中)** ```c // 1. 定义控制文件数组 (e.g., 内存子系统) static struct cftype mem_cftypes[] = { { .name = "max", .flags = CFTYPE_NOT_ON_ROOT, // 不在root cgroup出现 .write = memory_max_write, // 写回调函数 .read = memory_current_read, // 读回调函数 }, { .name = "current", .flags = CFTYPE_NOT_ON_ROOT | CFTYPE_DEBUG, .seq_show = memory_current_show, // 序列化显示 }, { } // 终止符 }; // 2. 在子系统初始化时注册 static int __init mem_cgroup_init(void) { int ret; // ... 其他初始化 ret = cgroup_add_dfl_cftypes(&memory_cgrp_subsys, mem_cftypes); // 关键调用 if (ret) goto out; // ... } ``` * **结果**:所有属于 `memory` 控制器的 cgroup v2 层级下,都会出现 `memory.max` 和 `memory.current` 文件,用于设置/查询内存限制和使用量。 --- ### **四、与 cgroup v1 的区别** * **v1 接口**:使用 `cgroup_add_cftypes()` 或 `cgroup_add_legacy_cftypes()`,注册到 `/sys/fs/cgroup/<controller>/` 目录下的文件可能出现在多个层级。 * **v2 接口**:`cgroup_add_dfl_cftypes()` 注册的文件**仅出现在统一的 v2 层级** (`/sys/fs/cgroup/` 或其子目录),符合 v2 的单一层次结构设计[^1][^4]。 --- ### **五、总结** `cgroup_add_dfl_cftypes()` 是 **cgroup v2 子系统动态扩展其用户控制接口**的核心机制: 1. **作用**:向指定的 cgroup v2 层级注册一组控制文件 (`cftypes`)。 2. **原理**: * 校验 v2 层级。 * 遍历 `cfts` 数组,将每个 `cftype` 绑定到层级。 * 通过 `kernfs` 在 cgroup 目录下创建文件节点,关联读写回调。 * 管理 `cftype` 链表。 3. **关键**:`cftype` 定义了文件名、属性及读写回调函数,**子系统通过回调函数实现具体的资源控制逻辑**。 4. **结果**:用户通过读写 `/sys/fs/cgroup/` 下的文件,即可配置和查询 cgroup 的资源限制,这些操作最终由子系统定义的回调函数处理[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值