start_kernel之cgroup_init_early函数

cgroup原理:可以参考美团的文章来理解:Linux资源管理之cgroups简介

函数流程

函数作用:cgroup初始化,并按照是否需要early_init(Bool)配置,初始化相关的子系统

在这里插入图片描述

cgroup支持的各子系统

cpuset

/* kernel/cgroup/cpuset.c */

struct cgroup_subsys cpuset_cgrp_subsys = {
.css_alloc = cpuset_css_alloc,
.css_online = cpuset_css_online,
.css_offline = cpuset_css_offline,
.css_free = cpuset_css_free,
.can_attach = cpuset_can_attach,
.cancel_attach = cpuset_cancel_attach,
.attach = cpuset_attach,
.post_attach = cpuset_post_attach,
.bind = cpuset_bind,
.fork = cpuset_fork,
.legacy_cftypes = legacy_files,
.dfl_cftypes = dfl_files,
.early_init = true,
.threaded = true,
};

cpu

// kernel/sched/core.c

struct cgroup_subsys cpu_cgrp_subsys = {
.css_alloc = cpu_cgroup_css_alloc,
.css_online = cpu_cgroup_css_online,
.css_released = cpu_cgroup_css_released,
.css_free = cpu_cgroup_css_free,
.css_extra_stat_show = cpu_extra_stat_show,
.fork = cpu_cgroup_fork,
.can_attach = cpu_cgroup_can_attach,
.attach = cpu_cgroup_attach,
.legacy_cftypes = cpu_legacy_files,
.dfl_cftypes = cpu_files,
.early_init = true,
.threaded = true,
};

cpuacct

// kernel/sched/cpuacct.c

struct cgroup_subsys cpuacct_cgrp_subsys = {
.css_alloc = cpuacct_css_alloc,
.css_free = cpuacct_css_free,
.legacy_cftypes = files,
.early_init = true,
};

io

// block/blk-cgroup.c

struct cgroup_subsys io_cgrp_subsys = {
.css_alloc = blkcg_css_alloc,
.css_online = blkcg_css_online,
.css_offline = blkcg_css_offline,
.css_free = blkcg_css_free,
.can_attach = blkcg_can_attach,
.css_rstat_flush = blkcg_rstat_flush,
.bind = blkcg_bind,
.dfl_cftypes = blkcg_files,
.legacy_cftypes = blkcg_legacy_files,
.legacy_name = "blkio",
.exit = blkcg_exit,
.depends_on = 1 << memory_cgrp_id,
};

memory

// mm/memcontrol.c

struct cgroup_subsys memory_cgrp_subsys = {
.css_alloc = mem_cgroup_css_alloc,
.css_online = mem_cgroup_css_online,
.css_offline = mem_cgroup_css_offline,
.css_released = mem_cgroup_css_released,
.css_free = mem_cgroup_css_free,
.css_reset = mem_cgroup_css_reset,
.can_attach = mem_cgroup_can_attach,
.cancel_attach = mem_cgroup_cancel_attach,
.post_attach = mem_cgroup_move_task,
.dfl_cftypes = memory_files,
.legacy_cftypes = mem_cgroup_legacy_files,
.early_init = 0,
};

devices

// security/device_cgroup.c

struct cgroup_subsys devices_cgrp_subsys = {
.css_alloc = devcgroup_css_alloc,
.css_free = devcgroup_css_free,
.css_online = devcgroup_online,
.css_offline = devcgroup_offline,
.legacy_cftypes = dev_cgroup_files,
};

perf_event

// kernel/events/core.c

struct cgroup_subsys perf_event_cgrp_subsys = {
.css_alloc = perf_cgroup_css_alloc,
.css_free = perf_cgroup_css_free,
.css_online = perf_cgroup_css_online,
.attach = perf_cgroup_attach,
.implicit_on_dfl = true,
.threaded = true,
};

hugetlb

// mm/hugetlb_cgroup.c

struct cgroup_subsys hugetlb_cgrp_subsys = {
.css_alloc = hugetlb_cgroup_css_alloc,
.css_offline = hugetlb_cgroup_css_offline,
.css_free = hugetlb_cgroup_css_free,
.dfl_cftypes = hugetlb_files,
.legacy_cftypes = hugetlb_files,
};

pids

// kernel/cgroup/pids.c

struct cgroup_subsys pids_cgrp_subsys = {
.css_alloc = pids_css_alloc,
.css_free = pids_css_free,
.can_attach = pids_can_attach,
.cancel_attach = pids_cancel_attach,
.can_fork = pids_can_fork,
.cancel_fork = pids_cancel_fork,
.release = pids_release,
.legacy_cftypes = pids_files,
.dfl_cftypes = pids_files,
.threaded = true,
};
<think> 我们正在讨论Linux内核中的一个配置选项:CONFIG_KERNEL_CGROUP_NET_CLASSID。根据引用内容,我们了解到cgroup(控制组)是Linux内核中用于资源管理的一种机制。它通过将进程分组,并与subsystem(子系统)关联,从而实现对资源(如CPU、内存、网络等)的控制。 具体到CONFIG_KERNEL_CGROUP_NET_CLASSID,这个配置选项属于cgroup的network子系统(network controller)。它的作用是为cgroup提供一个网络类标识符(classid),用于网络流量控制(traffic control)。这个标识符可以被用来标记属于某个cgroup的所有网络数据包,然后通过tc(traffic control工具)对这些数据包进行不同的处理,比如优先级调度、带宽限制等。 ### 作用详解: 1. **网络流量分类**:当网络数据包从属于某个cgroup的进程发出时,内核会为这些数据包打上该cgroup的classid标记。 2. **流量控制**:在网络设备上配置的tc规则可以根据这个classid对数据包进行分类,进而应用不同的队列规则(如HTB、CBQ等)来实现带宽分配、优先级控制等。 3. **应用场景**:在容器环境中(如Docker),可以为每个容器设置一个cgroup,并分配不同的网络classid,从而实现容器间的网络带宽隔离和QoS保障。 ### 内核实现: 在cgroup的network子系统中,每个cgroup都有一个`net_cls.classid`文件。通过向该文件写入一个32位的十六进制数(如0x100001)来设置该cgroup的classid。内核网络栈在发送数据包时会检查发送进程所属的cgroup,并将classid设置到skb(socket buffer)中。 ### 配置选项的位置: 在内核配置中,该选项通常位于: ``` Networking support -> Networking options -> Control Group support -> Network classid ``` 配置选项名为:`CONFIG_CGROUP_NET_CLASSID`(注意:在较新内核中,前缀可能为`CONFIG_CGROUP_NET_CLASSID`,但根据用户提供的配置选项名称,这里可能是`CONFIG_KERNEL_CGROUP_NET_CLASSID`,这可能是特定内核版本或发行版的命名,通常内核中为`CONFIG_CGROUP_NET_CLASSID`)。 ### 使用示例: 1. 挂载cgroup(如果尚未挂载): ```bash mount -t cgroup -o net_cls net_cls /sys/fs/cgroup/net_cls ``` 2. 创建一个cgroup: ```bash mkdir /sys/fs/cgroup/net_cls/group1 ``` 3. 设置classid(格式为十六进制,但写入时通常用十进制,如0x100001对应的十进制为1048577): ```bash echo 1048577 > /sys/fs/cgroup/net_cls/group1/net_cls.classid ``` 4. 将进程加入该cgroup: ```bash echo <pid> > /sys/fs/cgroup/net_cls/group1/tasks ``` 5. 使用tc工具配置网络设备(如eth0)的队列规则,根据classid进行流量控制。 ### 注意事项: - 该功能需要内核编译时开启`CONFIG_CGROUP_NET_CLASSID`(或用户所写的`CONFIG_KERNEL_CGROUP_NET_CLASSID`)。 - 需要tc工具的支持,并且需要正确配置tc过滤器(filter)和类(class)。 ### 引用说明: 根据引用[3]和[4]中关于cgroup基本概念的描述,我们可以理解cgroup的组成和网络子系统的作用。而classid正是网络子系统提供的一个控制点[^3][^4]。 §§相关问题§§ 1. 如何在Docker容器中利用cgroup的net_cls进行网络流量控制? 2. 如何通过tc工具配置基于classid的带宽限制? 3. 在较新的内核中(如v5.4以上),cgroup v2对网络控制的支持有哪些变化? </think> ### **CONFIG_KERNEL_CGROUP_NET_CLASSID 的作用详解** `CONFIG_KERNEL_CGROUP_NET_CLASSID` 是 Linux 内核中一个与 **cgroup 网络流量控制**相关的关键配置选项,其主要作用是为 cgroup 提供网络流量分类标识(classid)。以下是具体分析: --- ### **一、核心作用** 1. **流量分类标识** 启用该选项后,系统会为每个 cgroup 分配唯一的网络类标识符(classid)。该标识符用于: - 标记属于特定 cgroup 的所有网络数据包 - 在流量控制(Traffic Control, TC)子系统中识别不同 cgroup 的网络流[^3][^5] 2. **QoS 和带宽控制** 结合 `tc`(Traffic Control)工具,可实现: - 基于 cgroup 的带宽限制(如限制某容器组的最大带宽) - 流量优先级调度(如保证关键服务的网络质量) - 流量整形(如平滑突发流量)[^1][^4] 3. **容器网络隔离** 在容器化环境中(如 Docker/Kubernetes): - 为每个容器分配独立的 classid - 确保容器间网络资源隔离 - 防止单个容器耗尽主机网络资源[^3][^5] --- ### **二、技术实现原理** #### 1. **cgroup 层级关联** - 当启用此选项时,内核会在 `net_cls` 子系统(subsystem)中创建 `classid` 文件 - 每个 cgroup 节点自动生成唯一标识符,继承关系遵循 cgroup 层级规则[^3][^4] ```bash /sys/fs/cgroup/net_cls/ ├── cgroup.procs ├── net_cls.classid # 存储 classid 值(如 0x100001) └── tasks ``` #### 2. **内核数据流** - 进程发送网络数据包时,内核检查其所属 cgroup 的 `classid` - 将 classid 写入 sk_buff 结构体(网络数据包的内核表示) - TC 子系统通过 `cls_cgroup` 分类器识别 classid 并应用策略[^1] ```c // 内核源码示例(简化) struct cgroup_subsys net_cls_subsys = { .name = "net_cls", .attach = net_cls_attach, }; ``` #### 3. **典型应用场景** ```bash # 设置 cgroup 的 classid echo 0x100001 > /sys/fs/cgroup/net_cls/group1/net_cls.classid # 使用 tc 限制该 cgroup 的带宽为 10Mbps tc qdisc add dev eth0 root handle 1: htb tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit tc filter add dev eth0 parent 1: protocol ip handle 1: cgroup ``` --- ### **三、启用条件与依赖** 1. **内核配置要求** 需同时启用: ```bash CONFIG_CGROUPS=y # 启用 cgroup 基础功能 CONFIG_NET_CLS_CGROUP=y # 启用网络 classid 子系统 ``` 2. **用户空间工具** 依赖 `iproute2` 软件包中的 `tc` 工具进行策略配置: ```bash tc filter show dev eth0 # 查看已应用的 classid 规则 ``` --- ### **四、实际应用案例** #### **容器网络限速(Docker)** 1. 创建带网络 classid 的 cgroup: ```bash docker run --cgroup-parent=/net_cls/group1 --name mycontainer nginx ``` 2. 限制容器带宽为 5Mbps: ```bash tc class add dev eth0 parent 1: classid 1:10 htb rate 5mbit tc filter add dev eth0 parent 1: protocol ip handle 10 cgroup ``` --- ### **总结** `CONFIG_KERNEL_CGROUP_NET_CLASSID` 是 Linux cgroup 网络资源控制的基石,它通过为每个 cgroup 分配唯一网络标识符,实现了: - 📦 **精细化的网络 QoS 控制** - 🛡️ **容器/进程级的网络资源隔离** - ⚙️ **基于 tc 的动态带宽管理** 在容器化、云计算等需要严格网络资源管理的场景中,该选项是保证服务质量和系统稳定的关键技术[^1][^3][^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值