|
| 1 | +.. SPDX-License-Identifier: GPL-2.0 |
| 2 | +.. include:: ../../../disclaimer-zh_CN.rst |
| 3 | + |
| 4 | +:Original: Documentation/admin-guide/mm/damon/usage.rst |
| 5 | + |
| 6 | +:翻译: |
| 7 | + |
| 8 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> |
| 9 | + |
| 10 | +:校译: |
| 11 | + |
| 12 | +======== |
| 13 | +详细用法 |
| 14 | +======== |
| 15 | + |
| 16 | +DAMON 为不同的用户提供了下面三种接口。 |
| 17 | + |
| 18 | +- *DAMON用户空间工具。* |
| 19 | + `这 <https://github.com/awslabs/damo>`_ 为有这特权的人, 如系统管理员,希望有一个刚好 |
| 20 | + 可以工作的人性化界面。 |
| 21 | + 使用它,用户可以以人性化的方式使用DAMON的主要功能。不过,它可能不会为特殊情况进行高度调整。 |
| 22 | + 它同时支持虚拟和物理地址空间的监测。更多细节,请参考它的 `使用文档 |
| 23 | + <https://github.com/awslabs/damo/blob/next/USAGE.md>`_。 |
| 24 | +- *debugfs接口。* |
| 25 | + :ref:`这 <debugfs_interface>` 是为那些希望更高级的使用DAMON的特权用户空间程序员准备的。 |
| 26 | + 使用它,用户可以通过读取和写入特殊的debugfs文件来使用DAMON的主要功能。因此,你可以编写和使 |
| 27 | + 用你个性化的DAMON debugfs包装程序,代替你读/写debugfs文件。 `DAMON用户空间工具 |
| 28 | + <https://github.com/awslabs/damo>`_ 就是这种程序的一个例子 它同时支持虚拟和物理地址 |
| 29 | + 空间的监测。注意,这个界面只提供简单的监测结果 :ref:`统计 <damos_stats>`。对于详细的监测 |
| 30 | + 结果,DAMON提供了一个:ref:`跟踪点 <tracepoint>`。 |
| 31 | + |
| 32 | +- *内核空间编程接口。* |
| 33 | + :doc:`This </vm/damon/api>` 这是为内核空间程序员准备的。使用它,用户可以通过为你编写内 |
| 34 | + 核空间的DAMON应用程序,最灵活有效地利用DAMON的每一个功能。你甚至可以为各种地址空间扩展DAMON。 |
| 35 | + 详细情况请参考接口 :doc:`文件 </vm/damon/api>`。 |
| 36 | + |
| 37 | + |
| 38 | +debugfs接口 |
| 39 | +=========== |
| 40 | + |
| 41 | +DAMON导出了八个文件, ``attrs``, ``target_ids``, ``init_regions``, |
| 42 | +``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` 和 |
| 43 | +``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``. |
| 44 | + |
| 45 | + |
| 46 | +属性 |
| 47 | +---- |
| 48 | + |
| 49 | +用户可以通过读取和写入 ``attrs`` 文件获得和设置 ``采样间隔`` 、 ``聚集间隔`` 、 ``区域更新间隔`` |
| 50 | +以及监测目标区域的最小/最大数量。要详细了解监测属性,请参考 `:doc:/vm/damon/design` 。例如, |
| 51 | +下面的命令将这些值设置为5ms、100ms、1000ms、10和1000,然后再次检查:: |
| 52 | + |
| 53 | + # cd <debugfs>/damon |
| 54 | + # echo 5000 100000 1000000 10 1000 > attrs |
| 55 | + # cat attrs |
| 56 | + 5000 100000 1000000 10 1000 |
| 57 | + |
| 58 | + |
| 59 | +目标ID |
| 60 | +------ |
| 61 | + |
| 62 | +一些类型的地址空间支持多个监测目标。例如,虚拟内存地址空间的监测可以有多个进程作为监测目标。用户 |
| 63 | +可以通过写入目标的相关id值来设置目标,并通过读取 ``target_ids`` 文件来获得当前目标的id。在监 |
| 64 | +测虚拟地址空间的情况下,这些值应该是监测目标进程的pid。例如,下面的命令将pid为42和4242的进程设 |
| 65 | +为监测目标,并再次检查:: |
| 66 | + |
| 67 | + # cd <debugfs>/damon |
| 68 | + # echo 42 4242 > target_ids |
| 69 | + # cat target_ids |
| 70 | + 42 4242 |
| 71 | + |
| 72 | +用户还可以通过在文件中写入一个特殊的关键字 "paddr\n" 来监测系统的物理内存地址空间。因为物理地 |
| 73 | +址空间监测不支持多个目标,读取文件会显示一个假值,即 ``42`` ,如下图所示:: |
| 74 | + |
| 75 | + # cd <debugfs>/damon |
| 76 | + # echo paddr > target_ids |
| 77 | + # cat target_ids |
| 78 | + 42 |
| 79 | + |
| 80 | +请注意,设置目标ID并不启动监测。 |
| 81 | + |
| 82 | + |
| 83 | +初始监测目标区域 |
| 84 | +---------------- |
| 85 | + |
| 86 | +在虚拟地址空间监测的情况下,DAMON自动设置和更新监测的目标区域,这样就可以覆盖目标进程的整个 |
| 87 | +内存映射。然而,用户可能希望将监测区域限制在特定的地址范围内,如堆、栈或特定的文件映射区域。 |
| 88 | +或者,一些用户可以知道他们工作负载的初始访问模式,因此希望为“自适应区域调整”设置最佳初始区域。 |
| 89 | + |
| 90 | +相比之下,DAMON在物理内存监测的情况下不会自动设置和更新监测目标区域。因此,用户应该自己设置 |
| 91 | +监测目标区域。 |
| 92 | + |
| 93 | +在这种情况下,用户可以通过在 ``init_regions`` 文件中写入适当的值,明确地设置他们想要的初 |
| 94 | +始监测目标区域。输入的每一行应代表一个区域,形式如下:: |
| 95 | + |
| 96 | + <target idx> <start address> <end address> |
| 97 | + |
| 98 | +目标idx应该是 ``target_ids`` 文件中目标的索引,从 ``0`` 开始,区域应该按照地址顺序传递。 |
| 99 | +例如,下面的命令将设置几个地址范围, ``1-100`` 和 ``100-200`` 作为pid 42的初始监测目标 |
| 100 | +区域,这是 ``target_ids`` 中的第一个(索引 ``0`` ),另外几个地址范围, ``20-40`` 和 |
| 101 | +``50-100`` 作为pid 4242的地址,这是 ``target_ids`` 中的第二个(索引 ``1`` ):: |
| 102 | + |
| 103 | + # cd <debugfs>/damon |
| 104 | + # cat target_ids |
| 105 | + 42 4242 |
| 106 | + # echo "0 1 100 |
| 107 | + 0 100 200 |
| 108 | + 1 20 40 |
| 109 | + 1 50 100" > init_regions |
| 110 | + |
| 111 | +请注意,这只是设置了初始的监测目标区域。在虚拟内存监测的情况下,DAMON会在一个 ``区域更新间隔`` |
| 112 | +后自动更新区域的边界。因此,在这种情况下,如果用户不希望更新的话,应该把 ``区域的更新间隔`` 设 |
| 113 | +置得足够大。 |
| 114 | + |
| 115 | + |
| 116 | +方案 |
| 117 | +---- |
| 118 | + |
| 119 | +对于通常的基于DAMON的数据访问感知的内存管理优化,用户只是希望系统对特定访问模式的内存区域应用内 |
| 120 | +存管理操作。DAMON从用户那里接收这种形式化的操作方案,并将这些方案应用到目标进程中。 |
| 121 | + |
| 122 | +用户可以通过读取和写入 ``scheme`` debugfs文件来获得和设置这些方案。读取该文件还可以显示每个 |
| 123 | +方案的统计数据。在文件中,每一个方案都应该在每一行中以下列形式表示出来:: |
| 124 | + |
| 125 | + <target access pattern> <action> <quota> <watermarks> |
| 126 | + |
| 127 | +你可以通过简单地在文件中写入一个空字符串来禁用方案。 |
| 128 | + |
| 129 | +目标访问模式 |
| 130 | +~~~~~~~~~~~~ |
| 131 | + |
| 132 | +``<目标访问模式>`` 是由三个范围构成的,形式如下:: |
| 133 | + |
| 134 | + min-size max-size min-acc max-acc min-age max-age |
| 135 | + |
| 136 | +具体来说,区域大小的字节数( `min-size` 和 `max-size` ),访问频率的每聚合区间的监测访问次 |
| 137 | +数( `min-acc` 和 `max-acc` ),区域年龄的聚合区间数( `min-age` 和 `max-age` )都被指定。 |
| 138 | +请注意,这些范围是封闭区间。 |
| 139 | + |
| 140 | +动作 |
| 141 | +~~~~ |
| 142 | + |
| 143 | +``<action>`` 是一个预定义的内存管理动作的整数,DAMON将应用于具有目标访问模式的区域。支持 |
| 144 | +的数字和它们的含义如下:: |
| 145 | + |
| 146 | + - 0: Call ``madvise()`` for the region with ``MADV_WILLNEED`` |
| 147 | + - 1: Call ``madvise()`` for the region with ``MADV_COLD`` |
| 148 | + - 2: Call ``madvise()`` for the region with ``MADV_PAGEOUT`` |
| 149 | + - 3: Call ``madvise()`` for the region with ``MADV_HUGEPAGE`` |
| 150 | + - 4: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE`` |
| 151 | + - 5: Do nothing but count the statistics |
| 152 | + |
| 153 | +配额 |
| 154 | +~~~~ |
| 155 | + |
| 156 | +每个 ``动作`` 的最佳 ``目标访问模式`` 取决于工作负载,所以不容易找到。更糟糕的是,将某个 |
| 157 | +动作的方案设置得过于激进会导致严重的开销。为了避免这种开销,用户可以通过下面表格中的 ``<quota>`` |
| 158 | +来限制方案的时间和大小配额:: |
| 159 | + |
| 160 | + <ms> <sz> <reset interval> <priority weights> |
| 161 | + |
| 162 | +这使得DAMON在 ``<reset interval>`` 毫秒内,尽量只用 ``<ms>`` 毫秒的时间对 ``目标访 |
| 163 | +问模式`` 的内存区域应用动作,并在 ``<reset interval>`` 内只对最多<sz>字节的内存区域应 |
| 164 | +用动作。将 ``<ms>`` 和 ``<sz>`` 都设置为零,可以禁用配额限制。 |
| 165 | + |
| 166 | +当预计超过配额限制时,DAMON会根据 ``目标访问模式`` 的大小、访问频率和年龄,对发现的内存 |
| 167 | +区域进行优先排序。为了实现个性化的优先级,用户可以在 ``<优先级权重>`` 中设置这三个属性的 |
| 168 | +权重,具体形式如下:: |
| 169 | + |
| 170 | + <size weight> <access frequency weight> <age weight> |
| 171 | + |
| 172 | +水位 |
| 173 | +~~~~ |
| 174 | + |
| 175 | +有些方案需要根据系统特定指标的当前值来运行,如自由内存比率。对于这种情况,用户可以为该条 |
| 176 | +件指定水位。:: |
| 177 | + |
| 178 | + <metric> <check interval> <high mark> <middle mark> <low mark> |
| 179 | + |
| 180 | +``<metric>`` 是一个预定义的整数,用于要检查的度量。支持的数字和它们的含义如下。 |
| 181 | + |
| 182 | + - 0: 忽视水位 |
| 183 | + - 1: 系统空闲内存率 (千分比) |
| 184 | + |
| 185 | +每隔 ``<检查间隔>`` 微秒检查一次公制的值。 |
| 186 | + |
| 187 | +如果该值高于 ``<高标>`` 或低于 ``<低标>`` ,该方案被停用。如果该值低于 ``<中标>`` , |
| 188 | +该方案将被激活。 |
| 189 | + |
| 190 | +统计数据 |
| 191 | +~~~~~~~~ |
| 192 | + |
| 193 | +它还统计每个方案被尝试应用的区域的总数量和字节数,每个方案被成功应用的区域的两个数量,以 |
| 194 | +及超过配额限制的总数量。这些统计数据可用于在线分析或调整方案。 |
| 195 | + |
| 196 | +统计数据可以通过读取方案文件来显示。读取该文件将显示你在每一行中输入的每个 ``方案`` , |
| 197 | +统计的五个数字将被加在每一行的末尾。 |
| 198 | + |
| 199 | +例子 |
| 200 | +~~~~ |
| 201 | + |
| 202 | +下面的命令应用了一个方案:”如果一个大小为[4KiB, 8KiB]的内存区域在[10, 20]的聚合时间 |
| 203 | +间隔内显示出每一个聚合时间间隔[0, 5]的访问量,请分页出该区域。对于分页,每秒最多只能使 |
| 204 | +用10ms,而且每秒分页不能超过1GiB。在这一限制下,首先分页出具有较长年龄的内存区域。另外, |
| 205 | +每5秒钟检查一次系统的可用内存率,当可用内存率低于50%时开始监测和分页,但如果可用内存率 |
| 206 | +大于60%,或低于30%,则停止监测“:: |
| 207 | + |
| 208 | + # cd <debugfs>/damon |
| 209 | + # scheme="4096 8192 0 5 10 20 2" # target access pattern and action |
| 210 | + # scheme+=" 10 $((1024*1024*1024)) 1000" # quotas |
| 211 | + # scheme+=" 0 0 100" # prioritization weights |
| 212 | + # scheme+=" 1 5000000 600 500 300" # watermarks |
| 213 | + # echo "$scheme" > schemes |
| 214 | + |
| 215 | + |
| 216 | +开关 |
| 217 | +---- |
| 218 | + |
| 219 | +除非你明确地启动监测,否则如上所述的文件设置不会产生效果。你可以通过写入和读取 ``monitor_on`` |
| 220 | +文件来启动、停止和检查监测的当前状态。写入 ``on`` 该文件可以启动对有属性的目标的监测。写入 |
| 221 | +``off`` 该文件则停止这些目标。如果每个目标进程被终止,DAMON也会停止。下面的示例命令开启、关 |
| 222 | +闭和检查DAMON的状态:: |
| 223 | + |
| 224 | + # cd <debugfs>/damon |
| 225 | + # echo on > monitor_on |
| 226 | + # echo off > monitor_on |
| 227 | + # cat monitor_on |
| 228 | + off |
| 229 | + |
| 230 | +请注意,当监测开启时,你不能写到上述的debugfs文件。如果你在DAMON运行时写到这些文件,将会返 |
| 231 | +回一个错误代码,如 ``-EBUSY`` 。 |
| 232 | + |
| 233 | + |
| 234 | +监测线程PID |
| 235 | +----------- |
| 236 | + |
| 237 | +DAMON通过一个叫做kdamond的内核线程来进行请求监测。你可以通过读取 ``kdamond_pid`` 文件获 |
| 238 | +得该线程的 ``pid`` 。当监测被 ``关闭`` 时,读取该文件不会返回任何信息:: |
| 239 | + |
| 240 | + # cd <debugfs>/damon |
| 241 | + # cat monitor_on |
| 242 | + off |
| 243 | + # cat kdamond_pid |
| 244 | + none |
| 245 | + # echo on > monitor_on |
| 246 | + # cat kdamond_pid |
| 247 | + 18594 |
| 248 | + |
| 249 | + |
| 250 | +使用多个监测线程 |
| 251 | +---------------- |
| 252 | + |
| 253 | +每个监测上下文都会创建一个 ``kdamond`` 线程。你可以使用 ``mk_contexts`` 和 ``rm_contexts`` |
| 254 | +文件为多个 ``kdamond`` 需要的用例创建和删除监测上下文。 |
| 255 | + |
| 256 | +将新上下文的名称写入 ``mk_contexts`` 文件,在 ``DAMON debugfs`` 目录上创建一个该名称的目录。 |
| 257 | +该目录将有该上下文的 ``DAMON debugfs`` 文件:: |
| 258 | + |
| 259 | + # cd <debugfs>/damon |
| 260 | + # ls foo |
| 261 | + # ls: cannot access 'foo': No such file or directory |
| 262 | + # echo foo > mk_contexts |
| 263 | + # ls foo |
| 264 | + # attrs init_regions kdamond_pid schemes target_ids |
| 265 | + |
| 266 | +如果不再需要上下文,你可以通过把上下文的名字放到 ``rm_contexts`` 文件中来删除它和相应的目录:: |
| 267 | + |
| 268 | + # echo foo > rm_contexts |
| 269 | + # ls foo |
| 270 | + # ls: cannot access 'foo': No such file or directory |
| 271 | + |
| 272 | +注意, ``mk_contexts`` 、 ``rm_contexts`` 和 ``monitor_on`` 文件只在根目录下。 |
| 273 | + |
| 274 | + |
| 275 | +监测结果的监测点 |
| 276 | +================ |
| 277 | + |
| 278 | +DAMON通过一个tracepoint ``damon:damon_aggregated`` 提供监测结果. 当监测开启时,你可 |
| 279 | +以记录追踪点事件,并使用追踪点支持工具如perf显示结果。比如说:: |
| 280 | + |
| 281 | + # echo on > monitor_on |
| 282 | + # perf record -e damon:damon_aggregated & |
| 283 | + # sleep 5 |
| 284 | + # kill 9 $(pidof perf) |
| 285 | + # echo off > monitor_on |
| 286 | + # perf script |
0 commit comments