首页 > 其他分享 >控制组 【ChatGPT】

控制组 【ChatGPT】

时间:2023-12-09 21:45:37浏览次数:23  
标签:任务 控制组 层次结构 cgroup ChatGPT 子系统 css

控制组

由Paul Menage [email protected]编写,基于CPUSETS

来自CPUSETS的原始版权声明:

部分版权所有(C)2004 BULL SA。

部分版权所有(c)2004-2006 Silicon Graphics, Inc.

由Paul Jackson [email protected]修改

由Christoph Lameter [email protected]修改

1. 控制组

1.1 什么是控制组?

控制组提供了一种将一组任务及其所有未来的子任务聚合/分区到具有特殊行为的分层组中的机制。

定义:

控制组将一组任务与一个或多个子系统的一组参数关联起来。

子系统是利用控制组提供的任务分组功能来以特定方式处理任务组的模块。子系统通常是“资源控制器”,用于调度资源或应用每个控制组的限制,但也可以是希望对一组进程进行操作的任何内容,例如虚拟化子系统。

层次结构是一组以树状排列的控制组,使得系统中的每个任务都恰好位于层次结构中的一个控制组中,并且一组子系统;每个子系统都附加到层次结构中的每个控制组上的特定状态。每个层次结构都有与之关联的控制组虚拟文件系统的实例。

在任何时候,可能存在多个活动的任务控制组层次结构。每个层次结构都是系统中所有任务的一个分区。

用户级代码可以在控制组虚拟文件系统的实例中按名称创建和销毁控制组,指定和查询任务分配到哪个控制组,以及列出分配给控制组的任务PID。这些创建和分配只影响与该控制组文件系统实例相关联的层次结构。

单独使用时,控制组的唯一用途是进行简单的作业跟踪。打算让其他子系统连接到通用控制组支持,以为控制组提供新的属性,例如对控制组中的进程访问资源进行会计/限制。例如,cpusets(参见CPUSETS)允许您将一组CPU和一组内存节点与每个控制组中的任务关联起来。

1.2 为什么需要控制组?

Linux内核中存在多个用于进程聚合的努力,主要用于资源跟踪目的。这些努力包括cpusets、CKRM/ResGroups、UserBeanCounters和虚拟服务器命名空间。这些都需要基本的进程分组/分区概念,使新分叉的进程最终进入与其父进程相同的组(控制组)。

内核控制组补丁提供了有效实现这些组所需的最小基本内核机制。它对系统快速路径几乎没有影响,并为特定子系统提供了钩子,例如cpusets,以提供所需的附加行为。

提供多层次结构支持,以允许在不同子系统中将任务分割为完全不同的情况 - 具有并行层次结构允许每个层次结构成为任务的自然分割,而无需处理如果几个不相关的子系统需要强制进入相同的控制组树中将存在的复杂组合任务。

在一个极端情况下,每个资源控制器或子系统可以位于单独的层次结构中;在另一个极端情况下,所有子系统都将附加到相同的层次结构中。

作为一个可以受益于多层次结构的场景的例子(最初由[email protected]提出),考虑一个具有各种用户(学生、教授、系统任务等)的大型大学服务器的资源规划,可以如下进行:

CPU:          “顶级cpuset”
                /       \
        CPUSet1         CPUSet2
           |               |
        (教授)       (学生)

此外(系统任务)附加到topcpuset(以便它们可以在任何地方运行),并限制为20%

内存:教授(50%),学生(30%),系统(20%)

磁盘:教授(50%),学生(30%),系统(20%)

网络:WWW浏览(20%),网络文件系统(60%),其他(20%)
                        / \
        教授(15%)    学生(5%)

像Firefox/Lynx这样的浏览器进入WWW网络类,而(k)nfsd进入NFS网络类。

同时,Firefox/Lynx将根据启动它的人(教授/学生)共享适当的CPU/内存类。

通过为不同资源不同地对任务进行分类(通过将这些资源子系统放入不同的层次结构中),管理员可以轻松设置一个脚本,该脚本接收执行通知,并根据启动浏览器的人来执行以下操作:

# echo browser_pid > /sys/fs/cgroup/<restype>/<userclass>/tasks

现在只有一个层次结构,他可能需要为每个启动的浏览器创建一个单独的控制组,并将其与适当的网络和其他资源类关联起来。这可能导致这些控制组的激增。

另外,假设管理员希望临时为学生的浏览器提供增强的网络访问权限(因为现在是晚上,用户想要进行在线游戏:))或者为学生的模拟应用程序提供增强的CPU性能。

通过直接将PID写入资源类,只需:

# echo pid > /sys/fs/cgroup/network/<new_class>/tasks
(一段时间后)
# echo pid > /sys/fs/cgroup/network/<orig_class>/tasks

如果没有这种能力,管理员将不得不将控制组分割为多个单独的控制组,然后将新的控制组与新的资源类关联起来。

1.3 控制组是如何实现的?

控制组扩展了内核,具体如下:

  • 系统中的每个任务都有一个引用计数指针指向css_set。

  • css_set包含一组引用计数指针,指向系统中注册的每个控制组子系统的cgroup_subsys_state对象。从任务到其在每个层次结构中的控制组的直接链接不存在,但可以通过cgroup_subsys_state对象的指针跟踪来确定这一点。这是因为访问子系统状态是预期频繁发生且在性能关键代码中发生的事情,而需要任务的实际控制组分配(特别是在控制组之间移动)的操作不太常见。通过css_set->tasks锚定的链接列表通过css_set运行。

  • 可以挂载控制组层次结构文件系统以进行浏览和操作。

  • 可以列出附加到任何控制组的所有任务(按PID)。

控制组的实现需要在内核的其余部分中添加一些简单的钩子,但不会影响性能关键路径:

  • 在init/main.c中,用于在系统引导时初始化根控制组和初始css_set。

  • 在fork和exit中,用于将任务附加到其css_set并从中分离。

此外,可以挂载类型为“cgroup”的新文件系统,以便从用户空间浏览和修改内核当前已知的控制组。挂载控制组文件系统时,可以通过文件系统挂载选项指定以逗号分隔的子系统列表。默认情况下,挂载控制组文件系统会尝试挂载包含所有已注册子系统的层次结构。

如果已经存在具有完全相同子系统集的活动层次结构,则将重用该层次结构用于新的挂载。如果没有现有的层次结构与之匹配,并且任何请求的子系统在现有层次结构中正在使用,则挂载将失败,并显示-EBUSY。否则,将激活新的层次结构,并与请求的子系统关联。

目前不可能将新的子系统绑定到活动的控制组层次结构,也不可能从活动的控制组层次结构中解绑子系统。这可能在将来可能实现,但存在严重的错误恢复问题。

当卸载控制组文件系统时,如果在顶级控制组下创建了任何子控制组,则即使卸载了,该层次结构仍将保持活动状态;如果没有子控制组,则该层次结构将被停用。

控制组没有添加新的系统调用 - 所有查询和修改控制组的支持都通过控制组文件系统进行。

/proc下的每个任务都有一个名为'cgroup'的附加文件,显示每个活动层次结构的子系统名称和作为相对于控制组文件系统根的路径的控制组名称。

每个控制组由控制组文件系统中的一个目录表示,其中包含描述该控制组的以下文件:

  • tasks:附加到该控制组的任务(按PID)列表。不能保证此列表已排序。将线程ID写入此文件会将线程移动到此控制组中。

  • cgroup.procs:控制组中线程组ID的列表。不能保证此列表已排序或不包含重复的TGID,如果需要此属性,则用户空间应对列表进行排序/去重。将线程组ID写入此文件会将该组中的所有线程移动到此控制组中。

  • notify_on_release标志:在退出时运行释放代理程序?

  • release_agent:用于释放通知的路径(此文件仅存在于顶级控制组中)

其他子系统(例如cpusets)可能会在每个控制组目录中添加其他文件。

使用mkdir系统调用或shell命令创建新的控制组。通过写入该控制组目录中的适当文件来修改控制组的属性,例如其标志,如上所述。

嵌套控制组的命名层次结构允许将大型系统划分为嵌套的、动态可变的“软分区”。

每个任务的附加,由该任务的任何子任务在分叉时自动继承,允许将系统上的工作负载组织成相关的任务集。如果允许在必要的控制组文件系统目录上进行操作,则可以将任务重新附加到任何其他控制组。

当将任务从一个控制组移动到另一个控制组时,它将获得一个新的css_set指针 - 如果已经存在具有所需控制组集合的css_set,则将重用该组,否则将分配一个新的css_set。通过查找哈希表来定位适当的现有css_set。

为了允许从控制组访问组成它的css_sets(因此任务),一组cg_cgroup_link对象形成一个格点;每个cg_cgroup_link链接到其cgrp_link_list字段上的单个控制组的cg_cgroup_links列表,以及链接到其cg_link_list字段上的单个css_set的cg_cgroup_links列表。

因此,可以通过迭代引用控制组的每个css_set,并在每个css_set的任务集上进行子迭代,列出控制组中的任务集。

使用Linux虚拟文件系统(vfs)表示控制组层次结构提供了熟悉的权限和名称空间,几乎不需要额外的内核代码。

1.4 notify_on_release 是什么作用?

如果在一个 cgroup 中启用了 notify_on_release 标志(1),那么每当该 cgroup 中的最后一个任务离开(退出或附加到其他 cgroup)并且该 cgroup 的最后一个子 cgroup 被移除时,内核会运行该层次结构根目录中“release_agent”文件中指定的命令,同时提供被遗弃 cgroup 的路径名(相对于 cgroup 文件系统的挂载点)。这使得自动移除被遗弃的 cgroups 成为可能。系统启动时,根 cgroup 中 notify_on_release 的默认值为禁用(0)。其他 cgroups 在创建时的默认值为其父级 notify_on_release 设置的当前值。cgroup 层次结构的 release_agent 路径的默认值为空。

1.5 clone_children 是什么作用?

此标志仅影响 cpuset 控制器。如果在一个 cgroup 中启用了 clone_children 标志(1),则在初始化期间,新的 cpuset cgroup 将从其父级复制其配置。

1.6 如何使用 cgroups?

要启动一个要包含在 cgroup 中的新作业,使用“cpuset” cgroup 子系统的步骤如下:

  1. 挂载 -t tmpfs cgroup_root /sys/fs/cgroup
  2. mkdir /sys/fs/cgroup/cpuset
  3. mount -t cgroup -ocpuset cpuset /sys/fs/cgroup/cpuset
  4. 通过在 /sys/fs/cgroup/cpuset 虚拟文件系统中进行 mkdir 和 write(或 echo)来创建新的 cgroup。
  5. 启动一个将成为新作业“创始人”的任务。
  6. 通过将其 PID 写入该 cgroup 的 /sys/fs/cgroup/cpuset tasks 文件,将该任务附加到新的 cgroup。
  7. 从这个创始人任务 fork、exec 或 clone 作业任务。

例如,以下命令序列将设置一个名为“Charlie”的 cgroup,其中只包含 CPU 2 和 3,以及内存节点 1,然后在该 cgroup 中启动一个子 shell 'sh':

mount -t tmpfs cgroup_root /sys/fs/cgroup
mkdir /sys/fs/cgroup/cpuset
mount -t cgroup cpuset -ocpuset /sys/fs/cgroup/cpuset
cd /sys/fs/cgroup/cpuset
mkdir Charlie
cd Charlie
/bin/echo 2-3 > cpuset.cpus
/bin/echo 1 > cpuset.mems
/bin/echo $$ > tasks
sh
# 子 shell 'sh' 现在正在 cgroup Charlie 中运行
# 下一行应显示 '/Charlie'
cat /proc/self/cgroup

2. 用法示例和语法

2.1 基本用法

通过 cgroup 虚拟文件系统可以创建、修改和使用 cgroups。

要挂载具有所有可用子系统的 cgroup 层次结构,请输入:

# mount -t cgroup xxx /sys/fs/cgroup

“xxx” 不会被 cgroup 代码解释,但会出现在 /proc/mounts 中,因此可以是任何有用的标识字符串。

注意:某些子系统在没有用户输入的情况下无法工作。例如,如果启用了 cpusets,则用户必须在每个新创建的 cgroup 中填充 cpus 和 mems 文件,然后才能使用该组。

如 1.2 节“为什么需要 cgroups?”中所述,应为要控制的每个单一资源或资源组创建不同的 cgroup 层次结构。因此,应在 /sys/fs/cgroup 上挂载一个 tmpfs,并为每个 cgroup 资源或资源组创建目录:

# mount -t tmpfs cgroup_root /sys/fs/cgroup
# mkdir /sys/fs/cgroup/rg1

要挂载具有 cpuset 和 memory 子系统的 cgroup 层次结构,请输入:

# mount -t cgroup -o cpuset,memory hier1 /sys/fs/cgroup/rg1

目前支持重新挂载 cgroups,但不建议使用。重新挂载允许更改绑定的子系统和 release_agent。重新绑定几乎没有用处,因为它仅在层次结构为空时起作用,而 release_agent 本身应该被常规 fsnotify 替换。将来将删除重新挂载的支持。

要指定层次结构的 release_agent:

# mount -t cgroup -o cpuset,release_agent="/sbin/cpuset_release_agent" \
  xxx /sys/fs/cgroup/rg1

请注意,指定 'release_agent' 多于一次将返回失败。

请注意,目前仅在层次结构由单个(根)cgroup 组成时才支持更改子系统集。支持从现有 cgroup 层次结构中任意绑定/解绑子系统的能力预计将来会实现。

然后,在 /sys/fs/cgroup/rg1 下,您可以找到与系统中 cgroups 树相对应的树。例如,/sys/fs/cgroup/rg1 是保存整个系统的 cgroup。

如果要更改 release_agent 的值:

# echo "/sbin/new_release_agent" > /sys/fs/cgroup/rg1/release_agent

也可以通过重新挂载来更改。

如果要在 /sys/fs/cgroup/rg1 下创建一个新的 cgroup:

# cd /sys/fs/cgroup/rg1
# mkdir my_cgroup

现在您想对此 cgroup 做些什么:

# cd my_cgroup

在此目录中,您可以找到几个文件:

# ls
cgroup.procs notify_on_release tasks
(加上由附加子系统添加的任何其他文件)

现在将您的 shell 附加到此 cgroup:

# /bin/echo $$ > tasks

还可以通过在此目录中使用 mkdir 来在您的 cgroup 中创建 cgroups:

# mkdir my_sub_cs

要删除 cgroup,只需使用 rmdir:

# rmdir my_sub_cs

如果 cgroup 正在使用中(包含子 cgroups,或已附加进程,或被其他特定于子系统的引用保持活动),则此操作将失败。

2.2 附加进程

# /bin/echo PID > tasks

请注意,这是 PID,而不是 PIDs。一次只能附加一个任务。如果要附加多个任务,必须依次执行:

# /bin/echo PID1 > tasks
# /bin/echo PID2 > tasks
        ...
# /bin/echo PIDn > tasks

可以通过 echo 0 来附加当前 shell 任务:

# echo 0 > tasks

您可以使用 cgroup.procs 文件而不是 tasks 文件一次移动线程组中的所有线程。将线程组中任何任务的 PID 回显到 cgroup.procs 会导致将该线程组中的所有任务附加到 cgroup。将 0 写入 cgroup.procs 会将写入任务的线程组中的所有任务移动到 cgroup。

注意:由于每个任务始终是每个已挂载层次结构中的一个 cgroup 的成员,因此要将任务从当前 cgroup 中移除,必须将其移动到一个新的 cgroup(可能是根 cgroup)中,方法是将其写入新 cgroup 的 tasks 文件。

注意:由于某些 cgroup 子系统强制执行的一些限制,将进程移动到另一个 cgroup 可能会失败。

2.3 按名称挂载层次结构

在挂载 cgroups 层次结构时传递 name=<x> 选项会将给定名称与该层次结构关联起来。这可用于挂载预先存在的层次结构,以便通过名称而不是其一组活动子系统来引用它。每个层次结构要么没有名称,要么具有唯一名称。

名称应匹配 [w.-]+

在为新层次结构传递 name=<x> 选项时,需要手动指定子系统;当为子系统指定名称时,不支持当未显式指定子系统时自动挂载所有子系统的传统行为。

子系统的名称将作为层次结构描述的一部分出现在 /proc/mounts/proc/<pid>/cgroups 中。

3. 内核 API

3.1 概述

每个想要连接到通用 cgroup 系统的内核子系统都需要创建一个 cgroup_subsys 对象。这包含各种方法,这些方法是从 cgroup 系统的回调,以及一个子系统 ID,该 ID 将由 cgroup 系统分配。

cgroup_subsys 对象中的其他字段包括:

  • subsys_id:子系统的唯一数组索引,指示该子系统应该管理 cgroup->subsys[] 中的哪个条目。
  • name:应初始化为唯一的子系统名称。不应超过 MAX_CGROUP_TYPE_NAMELEN。
  • early_init:指示子系统是否需要在系统引导时进行早期初始化。

系统创建的每个 cgroup 对象都有一个指针数组,由子系统 ID 索引;这个指针完全由子系统管理;通用 cgroup 代码永远不会触及这个指针。

3.2 同步

cgroup 系统使用全局互斥锁 cgroup_mutex。任何想要修改 cgroup 的内容都应该获取该锁。也可以获取该锁以防止 cgroup 被修改,但在这种情况下可能更适合使用更具体的锁。

有关更多详细信息,请参阅 kernel/cgroup.c。

子系统可以通过函数 cgroup_lock()/cgroup_unlock() 获取/释放 cgroup_mutex。

可以通过以下方式访问任务的 cgroup 指针:

  • 在持有 cgroup_mutex 时
  • 在持有任务的 alloc_lock(通过 task_lock())时
  • 通过 rcu_read_lock() 段内部

3.3 子系统 API

每个子系统应该:

  • 在 linux/cgroup_subsys.h 中添加一个条目
  • 定义一个名为 <name>_cgrp_subsys 的 cgroup_subsys 对象

每个子系统可以导出以下方法。唯一强制的方法是 css_alloc/free。其他任何为空的方法都被认为是成功的空操作。

struct cgroup_subsys_state *css_alloc(struct cgroup *cgrp)(由调用者持有的 cgroup_mutex)

用于为 cgroup 分配子系统状态对象的方法。子系统应该为传入的 cgroup 分配其子系统状态对象,并在成功时返回指向新对象的指针或 ERR_PTR() 值。在成功时,子系统指针应该指向一个 cgroup_subsys_state 类型的结构体(通常嵌入在一个更大的子系统特定对象中),该结构体将由 cgroup 系统进行初始化。请注意,这将在初始化时调用,为该子系统创建根子系统状态;可以通过传入的 cgroup 对象具有 NULL 父对象(因为它是层次结构的根)来识别此情况,并且可能是初始化代码的适当位置。

int css_online(struct cgroup *cgrp)(由调用者持有的 cgroup_mutex)

在 @cgrp 成功完成所有分配并对 cgroup_for_each_child/descendant_*() 迭代器可见后调用。子系统可以选择通过返回 -errno 来失败创建。此回调可用于实现可靠的状态共享和沿层次结构传播。有关详细信息,请参阅 cgroup_for_each_descendant_pre() 的注释。

void css_offline(struct cgroup *cgrp)(由调用者持有的 cgroup_mutex)

这是 css_online() 的对应方法,仅当 css_online() 在 @cgrp 上成功调用时才调用。这表示 @cgrp 的结束开始。@cgrp 正在被移除,子系统应该开始放弃对 @cgrp 的所有引用。当所有引用都被释放后,cgroup 的移除将继续到下一步 - css_free()。在此回调之后,@cgrp 应被视为对子系统无效。

void css_free(struct cgroup *cgrp)(由调用者持有的 cgroup_mutex)

cgroup 系统即将释放 @cgrp;子系统应该释放其子系统状态对象。在调用此方法时,@cgrp 完全未使用;@cgrp->parent 仍然有效。(注意 - 如果在为新的 cgroup 调用此子系统的 create() 方法后发生错误,也可以调用此方法来释放新创建的 cgroup)。

int can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)(由调用者持有的 cgroup_mutex)

在将一个或多个任务移入 cgroup 之前调用;如果子系统返回错误,则会中止附加操作。@tset 包含要附加的任务,并保证至少有一个任务在其中。

如果任务集中有多个任务,则:

  • 可保证所有任务来自同一线程组
  • @tset 包含线程组中的所有任务,无论它们是否在切换 cgroup
  • 第一个任务是领导者

每个 @tset 条目还包含任务的旧 cgroup,不切换 cgroup 的任务可以使用 cgroup_taskset_for_each() 迭代器轻松跳过。请注意,这不会在 fork 上调用。如果此方法返回 0(成功),则在调用者持有 cgroup_mutex 的同时,这应该保持有效,并确保将来将调用 attach() 或 cancel_attach()。

void css_reset(struct cgroup_subsys_state *css)(由调用者持有的 cgroup_mutex)

一个可选操作,应将 @css 的配置恢复到初始状态。目前,这仅在统一层次结构上使用,当通过 "cgroup.subtree_control" 在 cgroup 上禁用子系统时,但应保持启用,因为其他子系统依赖于它。cgroup 核心通过删除相关的接口文件使这样的 css 不可见,并调用此回调,以便隐藏的子系统可以返回到初始中性状态。这样可以防止隐藏的 css 对资源控制产生意外影响,并确保在以后再次可见时配置处于初始状态。

void cancel_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)(由调用者持有的 cgroup_mutex)

在 can_attach() 成功后,任务附加操作失败时调用。具有一些副作用的子系统应提供此函数,以便子系统可以实现回滚。如果不提供,则不需要。这仅将调用已成功执行 can_attach() 操作的子系统。参数与 can_attach() 相同。

void attach(struct cgroup *cgrp, struct cgroup_taskset *tset)(由调用者持有的 cgroup_mutex)

在任务附加到 cgroup 后调用,以允许需要内存分配或阻塞的任何后附加活动。参数与 can_attach() 相同。

void fork(struct task_struct *task)

在任务被 fork 到 cgroup 时调用。

void exit(struct task_struct *task)

在任务退出时调用。

void free(struct task_struct *task)

在 task_struct 被释放时调用。

void bind(struct cgroup *root)(由调用者持有的 cgroup_mutex)

在将 cgroup 子系统重新绑定到不同的层次结构和根 cgroup 时调用。目前,这只涉及在默认层次结构(永远没有子 cgroup)和正在创建/销毁的层次结构之间的移动(因此没有子 cgroup)。

4. 扩展属性使用

cgroup 文件系统支持其目录和文件中的某些类型的扩展属性。当前支持的类型有:

  • Trusted(XATTR_TRUSTED)
  • Security(XATTR_SECURITY)

都需要 CAP_SYS_ADMIN 权限来设置。

与 tmpfs 中一样,cgroup 文件系统中的扩展属性使用内核内存存储,建议保持使用最小。这也是为什么不支持用户定义的扩展属性,因为任何用户都可以这样做,并且值大小没有限制。

目前已知使用此功能的用户是 SELinux,用于限制容器中 cgroup 的使用,以及 systemd,用于各种元数据,如 cgroup 中的主 PID(systemd 为每个服务创建一个 cgroup)。

5. 问题

Q: 关于这个 '/bin/echo' 是怎么回事?
A: bash 内建的 'echo' 命令不会检查对 write() 的调用是否出错。如果你在 cgroup 文件系统中使用它,你将无法知道命令是成功还是失败。

Q: 当我附加进程时,只有行中的第一个真正被附加了!
A: 我们每次调用 write() 只能返回一个错误代码。因此,你也应该只放置一个 PID。

标签:任务,控制组,层次结构,cgroup,ChatGPT,子系统,css
From: https://www.cnblogs.com/pengdonglin137/p/17891531.html

相关文章

  • Block IO 控制器 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/admin-guide/cgroup-v1/blkio-controller.htmlBlockIO控制器概述cgroup子系统"blkio"实现了块IO控制器。在存储层次结构中,似乎需要各种类型的IO控制策略(如比例带宽、最大带宽),无论是在叶节点还是在中间节点都需要。计划是使用......
  • CPU核算控制器 【ChatGPT】
    原文:https://www.kernel.org/doc/html/v6.6/admin-guide/cgroup-v1/cpuacct.htmlCPU核算控制器CPU核算控制器用于使用cgroups对任务进行分组,并核算这些任务组的CPU使用情况。CPU核算控制器支持多层级分组。一个核算组累积其所有子组和直接存在于其组中的任务的CPU使用情况。可......
  • RCU补丁审查清单 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/RCU/checklist.htmlRCU补丁审查清单本文档包含了一个用于生成和审查使用RCU的补丁的清单。违反以下列出的任何规则都会导致与省略锁原语相同类型的问题。这份清单基于审查这类补丁的经验,经历了相当长的一段时间,但总是欢迎改进!RCU是否......
  • Linux通用中断处理 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/genericirq.htmlLinux通用中断处理版权©2005-2010:ThomasGleixner©2005-2006:IngoMolnar简介通用中断处理层旨在为设备驱动程序提供完整的中断处理抽象。它能够处理所有不同类型的中断控制器硬件。设备驱动程序使用......
  • 循环缓冲区 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/circular-buffers.html循环缓冲区作者[email protected]@linux.ibm.comLinux提供了许多功能,可用于实现循环缓冲区。有两组这样的功能:用于确定2的幂大小缓冲区信息的便利函数。......
  • Linux中的红黑树(rbtree)【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/rbtree.html红黑树(rbtree)在Linux中日期2007年1月18日作者[email protected]红黑树是什么,它们有什么作用?红黑树是一种自平衡的二叉搜索树,用于存储可排序的键/值数据对。这与基数树(用于高效存储稀疏数组,因......
  • 本地原子操作的语义和行为 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/local_ops.html这篇文档介绍了本地原子操作的语义和行为,以及如何在任何给定的架构中实现它们,并展示了它们如何被正确地使用。它还强调了在读取这些本地变量时必须采取的预防措施,特别是当内存写入的顺序很重要时。注意请注意,......
  • 为内核对象添加引用计数器(krefs)【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/kref.html为内核对象添加引用计数器(krefs)作者[email protected]作者[email protected]其中很多内容都是从GregKroah-Hartman的2004年OLS论文和关于krefs的演示中借鉴而来的,可以在......
  • Linux kernel memory barriers 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/wrappers/memory-barriers.htmlLinux内核内存屏障免责声明本文档不是一个规范;它故意(为了简洁)和无意(因为是人类)不完整。本文档旨在指导如何使用Linux提供的各种内存屏障,但如果有任何疑问(而且有很多),请咨询。一些疑问可能通过参......
  • refcount_t API 与 atomic_t 的比较 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/refcount-vs-atomic.htmlrefcount_tAPI与atomic_t的比较介绍相关的内存排序类型函数比较非“读/修改/写”(RMW)操作基于增量的操作,不返回值基于减量的RMW操作,不返回值基于增量的RMW操作,返回值通用的减......