# 功能

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

系统性能受多个组件影响，包括 CPU 调度器、CPU 频率调节器、性能抽象层 (PerfHAL)、动态电压频率调节 (DVFS) 和内存管理。

Linux 内核提供 CPU 调度器、CPU 频率调节器、DVFS 和内存管理等标准功能。本指南对每个功能都进行了介绍并且提供了相关的参考资料链接。此外，PerfHAL 是 Qualcomm 为增强性能而增加的功能。

## CPU 调度器

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

CPU 调度器对在 Linux 系统中运行的进程的 CPU 时间分配进行管理。

CPU 架构使用 [Arm 大小核技术](https://www.arm.com/technologies/big-little)，包含以下核：

- 4 个大核 – 1 个超大核和 3 个大核
- 4 个小核

CPU 调度器使用 EEVDF（最早符合条件的虚拟截止时间优先）调度器，这是 Linux 内核提供的一种功能。EEVDF CPU 调度器使用“每实体负载跟踪”(PELT) 来监测任务的负载。

- 有关 EEVDF 调度器的更多信息，参见 [An EEVDF CPU scheduler for Linux](https://lwn.net/Articles/925371/)。
- 有关 PELT 的更多信息，参见 [Per-entity load tracking \[LWN.net\]](https://lwn.net/Articles/531853/)。

利用率钳位（UCLAMP 或 util clamp）是一种支持管理任务性能需求的调度器功能。如需了解更多信息，可访问 [https://docs.kernel.org/scheduler/sched-util-clamp.html](https://docs.kernel.org/scheduler/sched-util-clamp.html)。

相关信息，参见[定制 CPU 调度器](https://docs.qualcomm.com/doc/80-70014-10Y/topic/18-customize.html#customize-scheduler)。

## CPU 频率调节器

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

CPU 频率调节器负责调整 CPU 频率以响应系统负载，系统负载取决于正在执行的任务。CPU 调度器为该进程提供必要的输入。

Qualcomm Linux 使用 Linux 内核提供的 `schedutil` 调节器功能。

该调节器可在系统承受高负载时提高频率，在负载减少时降低频率，从而确保达到功耗与性能之间的最佳平衡。

有关 CPU 频率调节器的更多信息，可访问 [https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt](https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt) 和 [https://www.kernel.org/doc/html/v5.0/admin-guide/pm/cpufreq.html](https://www.kernel.org/doc/html/v5.0/admin-guide/pm/cpufreq.html)。

有关 CPU 频率调节器配置和定制的更多信息，参见[配置 CPU](https://docs.qualcomm.com/doc/80-70014-10Y/topic/14-configure.html#cpu) 和[定制 CPU 频率调节器](https://docs.qualcomm.com/doc/80-70014-10Y/topic/18-customize.html#cpu-frequency-governer)。

## DVFS 调节器

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

DVFS 调节器根据系统工作负载控制 CPU 缓存 (L3)、最后一级缓存控制器 (LLCC) 和 DDR 的频率。

这些调节器可在高工作负载时增加频率，在低工作负载时降低频率，从而确保在功耗与性能之间达到最佳平衡。

Qualcomm Linux 支持两种用于 L3 缓存、LLCC 和 DDR 的 DVFS 调节器。

### 静态映射 DVFS 调节器

这种调节器将 CPU L3 缓存和 DDR 的频率调整为与当前工作 CPU 的频率一致，以平衡功耗与性能要求。

例如，如果 CPU 频率达到其最大频率，则 L3 缓存和 DDR 的频率也必须达到最大值，才能实现性能与功耗的最佳平衡。

QCS6490 和 QCS5430 的静态映射在 kernel/arch/arm64/boot/dts/qcom/sc7280.dtsi 的源代码中。

有关定制选项，参见[定制静态映射 DVFS 调节器](https://docs.qualcomm.com/doc/80-70014-10Y/topic/18-customize.html#dvfs_0__section_u1x_jps_51c_caharris_03-20-24-2005-37-832)。

### BWMON 调节器

带宽监测 (BWMON) 调节器根据测得的从 CPU 流向 LLCC 再流向 DDR 的流量，动态调整 LLCC 和 DDR 的频率。

BWMON 硬件模块测量此流量。该模块在指定采样窗口内监测内存与其他子系统之间的数据吞吐量，并利用这一信息来调整 LLCC 和 DDR 频率，以满足所需带宽。

BWMON 调节器驱动程序可在 drivers/soc/qcom/icc-bwmon.c 的源代码中找到。

有关 BWMOM 的更多信息，参见 [\[PATCH v3 0/4\] soc/arm64: qcom: Add initial version of bwmon](https://lwn.net/ml/linux-kernel/20220531105137.110050-1-krzysztof.kozlowski@linaro.org/)。

有关定制选项，参见[定制 BWMON 调节器](https://docs.qualcomm.com/doc/80-70014-10Y/topic/18-customize.html#dvfs_0__section_qxs_4ps_51c_caharris_03-20-24-2007-2-926)。

## PerfHAL

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

PerfHAL 是 Qualcomm 专有的一项服务，该服务使 perflock API 可访问，从而提供附加功能。如需在短期内提高性能或降低功耗，可以使用该服务。

Perflock 可帮助修改系统行为，以管理间歇性工作负载。例如，如果特定的代码段必须在较高的 CPU 频率下运行一段时间，则可以在该代码中使用 perflock 来提高 CPU 频率。

PerfHAL 高效处理来自多个客户端的并行 perflock 请求。当有多个目标为同一个资源的请求时，PerfHAL 将这些请求聚合在一起，以达到设备所需的最佳性能水平。

当客户端的 perflock 不再处于活动状态时，PerfHAL 会释放与该客户端相关的所有 perflock。

### Perflock API

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

应用程序可以通过 Perflock API 基于具体用例调整系统参数，使之达到性能和功耗目标。

用户空间应用程序利用 perf\_lock\_acq() 和 perf\_lock\_rel() API 请求系统可调参数在设定时段或不确定时段内的具体值。

### 获取 perflock

perf\_lock\_acq() 函数用于获取 perflock 及必要优化列表。

该函数的语法为：`int perf_lock_acq(int handle, int duration, int list[], int numArgs)`。

- 其中的 duration 参数可设为具体时间或不确定时段 `(0)`。
- 无论是已设定时间还是确定的时段，一旦超出该时段，就会自动释放 perflock。
- 要手动释放设为不确定时段的 perflock，可使用 perf\_lock\_rel() 函数。

Table : perf_lock_acq API 参数

| 参数 | 说明 |
| --- | --- |
| `handle` | 标识客户端请求。 |
| `duration` | <ul class="ul" id="perflockapi__ul_fhn_fmz_q1c"><br>                                        <li class="li">表示需要拥有 perflock 的最长超时时间（单位为毫秒）。</li><br><br>                                        <li class="li"><code class="ph codeph">duration</code>有 2 种类型：确定和不确定<ul class="ul" id="perflockapi__ul_htm_rps_s1c"><br>                                                <li class="li">确定型 perflock 需要通过一个正整数值来指定最大超时时间。将创建一个定时器，定时器达到定时值时便会释放 perflock</li><br><br>                                                <li class="li">不确定型 perflock 将保留到客户端调用释放函数为止。</li><br><br>                                            </ul><br></li><br><br>                                    </ul> |
| `list` | 资源操作码和值对的数组：<br><ul class="ul" id="perflockapi__ul_vf1_dnz_q1c"><br>                                        <li class="li">操作码指示系统参数（资源）和设置值（级别）。</li><br><br>                                        <li class="li">操作码在以下文件中定义：<p class="p"><span class="ph filepath">sources\vendor\qcom\proprietary\perf-core\extnIntf\PerflocksResources.h</span>。</p><br></li><br><br>                                    </ul> |
| `numArgs` | 列表数组中的元素数。 |

Table : perf_lock_acq API 返回值和结果

| 返回值 | 结果 |
| --- | --- |
| 非零整数 | 成功 |
| -1 | 失败 |

### Perflock 释放

perf\_lock\_rel() 函数用于释放持有的 perflock。

如果 perflock 的持有时段是确定值，则无需调用 perf\_lock\_rel()，因为当持有时段达到设定值时会自动释放 perflock。要使用 perf\_lock\_rel() API，可以运行以下命令：

    int perf_lock_rel(int handle)Copy to clipboard

Table : perf_lock_rel API 参数

| 参数 | 说明 |
| --- | --- |
| `handle` | <ul class="ul" id="perflockapi__ul_vhd_bxz_q1c"><br>                                        <li class="li">跟踪唯一请求</li><br><br>                                        <li class="li">传递<br> <code class="ph codeph">perf_lock_acq</code> 返回的同一句柄以释放锁。</li><br><br>                                    </ul> |

Table : perf_lock_rel API 返回值和结果

| 返回值 | 结果 |
| --- | --- |
| 非零整数 | 成功 |
| -1 | 失败 |

### 资源操作码

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

Perflock 使用操作码及其相应值的组合对 perflock 资源执行特定操作。

一个 perflock 可接受多个操作码，这些操作码在 sources\vendor\qcom\proprietary\perf-core\extnIntf\PerflocksResources.h 的源代码中定义。

下表列出了支持的操作码：

Table : 支持的操作码

| 操作码 | Perflock 资源 | 用途 | 系统节点 |
| --- | --- | --- | --- |
| 0x44000000 | `MPCTLV3_UPSTREAM_SCHED_UTIL_CLAMP_MIN` | 设置单个任务和任务组可接受的最低性能级别。 | /proc/sys/kernel/sched\_util\_clamp\_min |
| 0x44004000 | `MPCTLV3_UPSTREAM_SCHED_UTIL_CLAMP_MAX` | 设置单个任务和任务组可接受的最高性能级别。 | /proc/sys/kernel/sched\_util\_clamp\_max |
| 0x44008100 | `MPCTLV3_UPSTREAM_SCALING_MIN_FREQ_LITTLE` | 设置小核群集的最小频率。 | /sys/devices/system/cpu/cpufreq/policy0/scaling\_min\_freq |
| 0x44008000 | `MPCTLV3_UPSTREAM_SCALING_MIN_FREQ_BIG` | 设置大核群集的最小频率。 | /sys/devices/system/cpu/cpufreq/policy4/scaling\_min\_freq |
| 0x44008200 | `MPCTLV3_UPSTREAM_SCALING_MIN_FREQ_PRIME` | 设置超大核群集的最小频率。 | /sys/devices/system/cpu/cpufreq/policy7/scaling\_min\_freq |
| 0x4400C100 | `MPCTLV3_UPSTREAM_SCALING_MAX_FREQ_LITTLE` | 设置小核群集的最大频率。 | /sys/devices/system/cpu/cpufreq/policy0/scaling\_max\_freq |
| 0x4400C000 | `MPCTLV3_UPSTREAM_SCALING_MAX_FREQ_BIG ` | 设置大核群集的最大频率。 | /sys/devices/system/cpu/cpufreq/policy4/scaling\_max\_freq |
| 0x4400C200 | `MPCTLV3_UPSTREAM_SCALING_MAX_FREQ_PRIME` | 设置超大核群集的最大频率。 | /sys/devices/system/cpu/cpufreq/policy7/scaling\_max\_freq |

以下是资源操作码的一些示例：

- 0x44004100, 1958400：这一对操作码和值表示小核群集的最小频率必须设置为 1958400 KHz。
- 0x44004100, 1958400, 0x44008100, 2100000：这一对操作码和值表示小核群集的最小频率必须设置为 1958400 KHz。小核群集的最大频率必须设置为 2100000 KHz。

有关如何使用和调试 perflock 的更多信息，参见[定制 perflock](https://docs.qualcomm.com/doc/80-70014-10Y/topic/18-customize.html#customize-perlocks)。

## 内存

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

软件分配内存时使用 RAM。有效管理 RAM 对满足性能要求及确保应用程序运行顺畅至关重要。

Figure : 内存分区
            ![](data:image/png;base64,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)

RAM 的某些部分独立于 Linux 系统进行管理。例如，从这些特定 RAM 分区运行的 Modem、视频和音频等固件。Linux 内核管理所有其他 RAM 分区。

Linux 内核自带内存管理子系统，其中包含以下组件：

- 实现虚拟内存和按需分页
- 内核内部结构与用户空间程序的内存分配
- 文件映射到进程的地址空间
- 其他内存管理操作

### RAM 内存分区

下表描述了各种类型的内存分配。

| RAM 分类 | 内存段 | 分配类型 | 说明 |
| --- | --- | --- | --- |
| 非 Linux | – | – | <ul class="ul" id="memory__ul_p5v_h2m_41c"><br>                                        <li class="li">除 Linux 外，各种子系统也通过划分的形式保留内存。</li><br><br>                                        <li class="li">这些划分形式在相应 DTSI 文件中指定。</li><br><br>                                    </ul> |
| Linux（系统 RAM） | 静态内核 | Vmlinux + 内核页结构 | <ul class="ul" id="memory__ul_gzq_52m_41c"><br>                                        <li class="li">此内存由内核在启动时保留，供自己使用。</li><br><br>                                        <li class="li">Vmlinux 内存用于存储 vmlinux 镜像。</li><br><br>                                        <li class="li">Vmlinux 镜像的大小和细分情况，可以从启动时的 dmesg 日志中获取：<ul class="ul" id="memory__ul_e2b_bfx_3bc_sshewale_05-10-24-1237-20-424"><br>                                                <li class="li"><br>                                                  <pre class="pre codeblock" id="memory__codeblock_yb4_hjm_qbc_sshewale_06-06-24-1520-13-586"><code>Memory: 3061872K/4134912K available (28800K kernel code, 2090K rwdata, 10688K rodata, 3072K init, 969K bss, 679824K reserved, 393216K cma-reserved)</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre><br>                                                </li><br><br>                                                <li class="li"><br>                                                  <pre class="pre codeblock" id="memory__codeblock_uzy_3jm_qbc_sshewale_06-06-24-1520-38-542"><code>Kernel code + rwdata + rodata+init +bss indicates vmlinux kernel image size (28800k+2090k+10688k+3072k+969k)</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre><br>                                                </li><br><br>                                            </ul><br></li><br><br>                                        <li class="li">内核页结构是内核在维护每一个 RAM 页的结构时所使用的内存。其计算方法为每 GB RAM 为 16 MB。</li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | Slab | <ul class="ul" id="memory__ul_mlr_t1r_51c_caharris_03-20-24-1456-13-798"><br>                                        <li class="li">Slab 由内核使用，旨在提高常用数据结构使用内存的速度和效率。</li><br><br>                                        <li class="li">要查看 slab 的内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_xng_v1r_51c_caharris_03-20-24-1456-41-577"><code>cat /proc/meminfo | grep -i slab</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                        <li class="li">要了解各种 slab 的分解及用法，可在内核配置中启用 <code class="ph codeph">CONFIG_SLUB_DEBUG</code>，然后运行以下命令：<pre class="pre codeblock" id="memory__codeblock_jfy_bbr_51c_caharris_03-20-24-1458-38-979"><code>cat /proc/slabinfo</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | 内核堆栈 | <ul class="ul" id="memory__ul_dpy_vbx_t1c_caharris_03-17-24-2104-3-233"><br>                                        <li class="li">内核堆栈存储每个进程的调用堆栈。</li><br><br>                                        <li class="li">要查看内核栈的内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_ypc_hbr_51c_caharris_03-20-24-1500-9-838"><code>cat /proc/meminfo | grep -i kernelstack</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | PageTables | <ul class="ul" id="memory__ul_omh_jbr_51c_caharris_03-20-24-1500-48-282"><br>                                        <li class="li">内核使用内存来存储将虚拟地址映射到物理地址的 PageTables</li><br><br>                                        <li class="li">要查看 PageTables 的内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_cjx_4br_51c_caharris_03-20-24-1502-26-888"><code>cat /proc/meminfo | grep -i PageTables</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | 模块 | <ul class="ul" id="memory__ul_lk4_qbr_51c_caharris_03-20-24-1502-55-991"><br>                                        <li class="li">以内核模块的形式表示动态加载到内核中的内核实体。</li><br><br>                                        <li class="li">要显示已加载内核模块的列表及其内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_cch_tbr_51c_caharris_03-20-24-1503-43-770"><code>cat /proc/modules</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | Vmalloc | <ul class="ul" id="memory__ul_t4t_vbr_51c_caharris_03-20-24-1504-27-363"><br>                                        <li class="li">用于分配虚拟连续内存。</li><br><br>                                        <li class="li">要查看 vmalloc 内存分解情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_lnx_xbr_51c_caharris_03-20-24-1505-5-185"><code>cat /proc/vmallocinfo</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | 缓存（内核 + 用户空间） | <ul class="ul" id="memory__ul_gys_zbr_51c_caharris_03-20-24-1505-37-238"><br>                                        <li class="li">驻留在 RAM 中的由文件支持的内存量。</li><br><br>                                        <li class="li">要查看缓存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_jd3_dcr_51c_caharris_03-20-24-1506-40-239"><code>cat /proc/meminfo | grep -i cached</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | 缓冲区 | <ul class="ul" id="memory__ul_g3t_vv2_4bc_sshewale_05-29-24-1054-24-346"><br>                                        <li class="li">缓冲区的大小固定，包含从磁盘读取或写入磁盘的信息块。</li><br><br>                                        <li class="li">要查看缓冲区内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_p22_3cr_51c_caharris_03-20-24-1508-5-447"><code>cat /proc/meminfo | grep -i Buffers</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 动态内核 | Shmem | <ul class="ul" id="memory__ul_lkb_1w2_4bc_sshewale_05-29-24-1055-40-115"><br>                                        <li class="li">共享内存是映射到两个或更多进程的地址空间的公共内存块。</li><br><br>                                        <li class="li">要查看共享内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_rtk_ncr_51c_caharris_03-20-24-1509-37-775"><code>cat /proc/meminfo | grep -i shmem</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 用户空间 | ZUSED (ZRAM) | 由 ZRAM 进行后压缩的匿名内存。 |
| Linux（系统 RAM） | 用户空间 | CMA | <ul class="ul" id="memory__ul_khp_pcr_51c_caharris_03-20-24-1510-15-988"><br>                                        <li class="li">物理连续内存通常映射到其他 IP（如视频和显示），但分配到 runtime。</li><br><br>                                        <li class="li">使用更多 CMA 预留内存会减少系统可以使用的空闲内存。CMA 预留的空闲内存只能用于可移动分配（如用户空间进程分配）。但不能用于内核分配。</li><br><br>                                    </ul> |
| Linux（系统 RAM） | 用户空间 | ANON | <ul class="ul" id="memory__ul_mss_bw2_4bc_sshewale_05-29-24-1056-9-392"><br>                                        <li class="li">用户空间应用程序使用 <span class="keyword apiname">malloc()</span> 或 <span class="keyword apiname">new()</span> 函数调用分配的内存。</li><br><br>                                        <li class="li">要获取进程的 ANON 内存分解，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_jr1_zcr_51c_caharris_03-20-24-1513-1-867"><code>cat /proc/&lt;pid&gt;/smaps</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 用户空间 | ION | <ul class="ul" id="memory__ul_km4_1dr_51c_caharris_03-20-24-1513-28-778"><br>                                        <li class="li">ION 内存允许在硬件 IP（如视频、摄像头和 Linux 软件）之间共享缓冲区。</li><br><br>                                        <li class="li">ION 管理一个或多个内存池，这些内存池在启动时可以预留出来以防止碎片化。</li><br><br>                                        <li class="li">要查看 ION 内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_zmc_vlg_v1c_caharris_03-22-24-1750-46-225"><code>mount -t debugfs none /sys/kernel/debug</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre><pre class="pre codeblock" id="memory__codeblock_rcx_ddr_51c_caharris_03-20-24-1514-27-337"><code>cat /sys/kernel/debug/dma_buf/bufinfo | grep bytes</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre><br>                                        </li><br><br>                                    </ul> |
| Linux（系统 RAM） | 用户空间 | KGSL | <ul class="ul" id="memory__ul_onb_3dr_51c_caharris_03-20-24-1515-40-628"><br>                                        <li class="li">图形驱动程序分配的内存。</li><br><br>                                        <li class="li">要查看内核图形支持层 (KGSL) 整体内存使用情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_pnf_kdr_51c_caharris_03-20-24-1516-18-485"><code>cat /sys/class/kgsl/kgsl/page_alloc</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre><br>                                        </li><br><br>                                        <li class="li">要查看进程级别分解情况，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_g4k_mdr_51c_caharris_03-20-24-1516-57-34"><code>cat /sys/class/kgsl/kgsl/proc/&lt;pid&gt;/kernel</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
| Linux（系统 RAM） | 空闲内存 | – | <ul class="ul" id="memory__ul_vrz_d2s_51c_caharris_03-20-24-1840-7-435"><br>                                        <li class="li">空闲内存是指尚未使用并可用于任何分配的内存。</li><br><br>                                        <li class="li">要查看空闲内存，可运行以下命令：<pre class="pre codeblock" id="memory__codeblock_u1g_qdr_51c_caharris_03-20-24-1518-4-285"><code>cat /proc/meminfo | grep -i MemFree</code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></li><br><br>                                    </ul> |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |

## 实时内核

Source: [https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70014-10Y/topic/2-performance-features.html)

实时 (RT) Linux 是一个可选功能，默认情况下在 Qualcomm Linux 平台上不启用。可以根据产品要求启用该功能。

RT Linux 旨在为时间敏感型应用提供确切并且可预测的行为。

### 搭建工作区

在 Qualcomm Linux 中，RT Linux 内核 recipe 称为 `linux-kernel-qcom-rt`。

Qualcomm Linux 内核支持 v6.6 LTS RT 内核，该内核通过 `meta-qcom-realtime` 层中 recipes-kernel/linux/linux-kernel-qcom-rt\_6.6.bb 的 Yocto recipe 进行维护。

有关如何克隆工作区以及获取使用 Qualcom RT Linux 所需的所有元数据层的更多信息，参见[如何与实时 Linux 同步并进行编译](https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-254Y/how_to.html#how-to-sync-and-build-with-real-time-linux-)。

### 启用 RT 内核

RT 内核是使用 Linux RT 内核 recipe 启用的。该 recipe 获取内核，下载抢占 RT 补丁，并将这些补丁应用于内核。它还可以通过以下配置启用可完全抢占的内核：

`CONFIG_PREEMPT_RT=y`。

有关 RT 内核的更多信息，参见[https://wiki.linuxfoundation.org/realtime/start](https://wiki.linuxfoundation.org/realtime/start)。

最后，在 recipes-kernel/linux/linux-kernel-qcom\_6.6.bb 源代码中添加以下 recipe。

    SECTION = "RT kernel"
    SUMMARY = "Linux Real time kernel for QCOM devices"
    DESCRIPTION = "Recipe to build real time Linux kernel"
     
    SRC_URI:append = "https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patch-6.6.14-rt21.patch.gz;md5sum=91969a704a73aa918c89d3027bdd3634 \
                     file://qcom_rt.cfg \
                     file://0001-arch-Kconfig-Add-RT-kernel-support.patch \
                     file://0001-printk-nbcon-move-locked-port-flag-to-struct-uart-port.patch \
                     "
     
    S = "${WORKDIR}/kernel"
    KERNEL_CONFIG_FRAGMENTS:append = " ${WORKDIR}/qcom_rt.cfg"
    Copy to clipboard

### 优化 RT 内核

以下是为了优化 RT 内核的性能而增加的一些配置：

# CONFIG_NO_HZ
    $ zcat proc/config.gz | grep NO_HZ
    CONFIG_NO_HZ_COMMON=y
    # CONFIG_NO_HZ_IDLE is not set
    CONFIG_NO_HZ_FULL=y
    # CONFIG_NO_HZ is not set
     #CONFIG_CPUSETS
    $ zcat proc/config.gz | grep CPUSETS
    CONFIG_CPUSETS=y
    Copy to clipboard

如果启用了 `CONFIG_NO_HZ_FULL`，该配置会阻止向只运行一个任务的 CPU 发送调度时钟中断。

`CONFIG_CPUSETS` 配置选项允许使用 CPUSETS，其中的 CPU 组成一个特定的集合来运行一组特定的任务。

有关 CPUSET 的信息，可访问 [https://docs.kernel.org/admin-guide/cgroup-v1/cpusets.html](https://docs.kernel.org/admin-guide/cgroup-v1/cpusets.html)。

### 验证内核类型

启动后，可通过运行以下命令验证内核类型：

    uname -v
    SMP PREMPT_RT
    Copy to clipboard

Last Published: Aug 20, 2024

[Previous Topic
入门指南](https://docs.qualcomm.com/bundle/publicresource/80-70014-10Y/topics/get-started.md) [Next Topic
分析工具](https://docs.qualcomm.com/bundle/publicresource/80-70014-10Y/topics/13-performance_tools.md)