diff --git a/study/arch/cache/Cache/1819162084-5da6c5734c9ad.png b/study/arch/cache/Cache/1819162084-5da6c5734c9ad.png
new file mode 100644
index 0000000..44fee88
Binary files /dev/null and b/study/arch/cache/Cache/1819162084-5da6c5734c9ad.png differ
diff --git a/study/arch/cache/Cache/8-way_set-associative_cache.jpg b/study/arch/cache/Cache/8-way_set-associative_cache.jpg
new file mode 100644
index 0000000..bbe82c6
Binary files /dev/null and b/study/arch/cache/Cache/8-way_set-associative_cache.jpg differ
diff --git a/study/arch/cache/Cache/README.md b/study/arch/cache/Cache/README.md
new file mode 100644
index 0000000..639c163
--- /dev/null
+++ b/study/arch/cache/Cache/README.md
@@ -0,0 +1,242 @@
+ ---
+
+title: 工具
+date: 2021-06-26 09:40
+author: gatieme
+tags:
+ - linux
+ - tools
+categories:
+ - 技术积累
+thumbnail:
+blogexcerpt: 虚拟化 & KVM 子系统
+
+---
+
+
+
+本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处, 谢谢合作
+
+
+
+因本人技术水平和知识面有限, 内容如有纰漏或者需要修正的地方, 欢迎大家指正, 鄙人在此谢谢啦
+
+**转载请务必注明出处, 谢谢, 不胜感激**
+
+
+
+| 日期 | 作者 | GitHub| CSDN | BLOG |
+| ------- |:-------:|:-------:|:-------:|:-------:|
+| 2021-02-15 | [成坚-gatieme](https://kernel.blog.csdn.net) | [`AderXCoding/system/tools/fzf`](https://github.com/gatieme/AderXCoding/tree/master/system/tools/fzf) | [使用模糊搜索神器 FZF 来提升办公体验](https://blog.csdn.net/gatieme/article/details/113828826) | [Using FZF to Improve Productivit](https://oskernellab.com/2021/02/15/2021/0215-0001-Using_FZF_to_Improve_Productivity)|
+
+
+
+
+
+[](https://www2.seas.gwu.edu/~bhagiweb/cs211/lectures/cache1.pdf)
+
+[](https://cs.slu.edu/~Efritts/CSCI224_S15/schedule/chap6-cache-memory.pptx)
+
+cache 是系统中的一块快速 SRAM, 价格高, 但是访问速度快, 可以减少 CPU 到 main memory 的 latency.
+
+cache 中的行为:
+
+| 动作 | 描述 |
+|:---:|:----:|
+| Cache hits | 表示可以在 cache 中, 查找到相应地址的 entry |
+| Cache Miss | 表示在 cache 中, 找不到相应地址的 entry. |
+| Snoop | cache 不断监视 transaction 的地址线, 来不间断的检查地址地址是否在 cache 中 |
+| Snarf | 从 main memory 中读出数据, 同时更新 cache 中的旧值 |
+| Dirty Data | cache 中的数据, 是最新的, 但是 main memory 中的数据还未更新, 称 cache 中的数据为 dirty. Stale Data 类似. |
+
+arm 架构中的 cache 架构是 harvard 结构的, 分为 data cache 和 inst cache.
+
+
+
+其中 L1 cache, 一般直接集成到 core 中, 大小多是 2-way, 4-way, 16KB 和 32KB, cache line 一般是 32byte 或者 64byte. 可以实现为 VIPT 或者 PIPT.
+
+L2 cache, 可以集成到 core 中, 也可以单独作为一个 external block, 大小多是 8-way 以上, 256KB, 512KB, 1M 等, cache line 也是 32byte, 64byte. 一般实现为 PIPT.
+
+# cache 架构
+-------
+
+cache 的架构, 分为 read architecture, write policy, allocation policy.
+
+1. read architecture
+
+read architecture 分为: Look Aside 和 Look Through.
+
+
+| 实现 | 描述 | 优点 | 缺点 |
+|:---:|:----:|:---:|:---:|
+| Look Aside | main memory 和 cache 都在同一时间, 看到同一 bus 上的 trans. | 减少了 cache miss 下的 memory 访问时间. | 在一个 core 访问 main memory 时, 另一个 core 不能访问 cache. |
+| Look Through | 不管是哪一种的 read architecture, cache miss 之后, 从 main memory 中得到的 value 都会被 Snarf 到 cache 中. | NA | NA |
+
+2. write policy
+
+write policy 分为 write back 和 write through.
+
+| 实现 | 描述 |
+|:---:|:----:|
+| write-back | 将数据写到 cache 中, cache 就像一个 buffer, 在 evict 一个新的 cache entry 时, 才会将 cache 写会 main memory.
存在 cache 和 main memory 的 consistency 问题. 需要进行 cache maintenance 操作 (如 cache line 置换, mmu page 置换修改等), 主要分为 cache invalid (舍弃 cache 中的值, 将 valid flag 置零) 和 cache update 操作 (更新 main memory 的值为 cache 中的值). |
+| write-Through | 读写性能要低一些, 但是 main memory 中都是最新的 value. 不存在 cache 和 main memory 的一致性问题. |
+
+3. allocation policy
+
+allocation policy 指的是 cache miss 之后, 是否 allocate 新的 entry.
+
+| 实现 | 描述 |
+|:---:|:----:|
+| read-allocated | 读操作 miss 之后, 先从 main memory 中读取数据给 core, 之后在进行 cache line snarf. |
+| write-allocated | 在 write miss 之后, 需要先进行 burst read, 进行 cache line snarf, 之后进行 write back 操作 (一般与 write back 一起使用). |
+
+
+# cache organization
+-------
+
+[请教 CPU 的 cache 中关于 line,block,index 等的理解 ?](https://www.zhihu.com/question/24612442/answer/156669729)
+
+## cache
+-------
+
+cache 由 set 组成, set 由 line 组成, line 由 valid bit, tag 和 data 组成. 其中 data 是真正要缓存的内存地址中的数据, 而 tag 是用来搜索 cache line 的标签.
+
+
+
+## cache 寻址的过程
+-------
+
+| tag | 主要存储 VA, PA 的地址索引. 平时所指的 cache size 并不包含 tag ram 的大小. |
+| offset 寻址具体的 word, index 寻址某一个 way, 也就是某一个 cache line, tag 主要做地址校对, 最终选择 tag 匹配的那一个 set.
+
+在 set-associate 结构的 cache 中, main memory 中所有 index 相同的地址, 都只能放在对应的 way 中.
+
+
+
+1. 根据 set index 找到 set
+
+2. 根据 tag 在 set 中搜索到 cache line
+
+ 如果 tag 匹配且 cacheline 有效, 则 cache 命中;
+
+ 如果没有命中, 就要根据置换策略找一个 cache line 把内存的数据加载到 cache line;
+
+3. 根据block offset 在 line 的 data 中找到值
+
+
+
+### 为什么需要 set
+-------
+
+为什么不能根据 tag 直接找到 cache line, 再根据 offset 找到值 ?
+
+
+cache 毕竟尽可能的快, 硬件要在几个纳秒内完成, 这就要求搜索是并行进行的, 如果 cache 中包括 100 cache line, 硬件就要并行比较 100 个 cache line 的 tag, 这无疑会增加硬件的复杂度和面积.
+
+
+这样, 利用分层的思想, 引入了 set 的层级, 先根据 set index 找出一个 set, 再在 set 中并行搜索有限个 cache line 就容易多了.
+
+
+> 为什么取内存地址的中间几位作为 set index ?
+>
+> 考虑空间局部性性原理, 下 cache 的利用率而进行的优化.
+
+
+# cache associativity
+-------
+
+引入了 set 之后, 整个 Cache 先划分为 M 个 Set, 每个 Set 包含了 N 个 Cache line.
+
+
+| 映射方式 | 描述 |
+|:------:|:----:|
+| 全相联映射(full-Associative) | 没有 cache page 的概念, 每个 cache line 直接对应到随机的某个 memory line
缺点是, TAG ram 会比较大, 索引会比较慢, 一般应用在 cache 较小的地方, 如 tlb 或者 predict buffer 中. |
+| 直接映射(Direct-Map) | 也称为 1-way associative, main memory 分为多个 cache page, 中的第 n line, 必须放在 cache page 的第 n 行. 复杂度不高, 但是, 性能很差, 常常需要 evict 其他的 cache line, 不够灵活. |
+| 组映射映射(N-way Set-Associative) | 比如 2-way, 4-way 等, 还有一个 Set 的概念, 表示 cache page 的行数. 每个组分为 N 份, N 称为 cache way. 每个 cache way 内部的映射, 就与 direct mapping 相同, set 到 main memory 的映射, 随意, 与 full-associative 相同. 所以一块 main memory, 首先随意映射一块地址到 set 中, 然后每个 set 在平分为几个 way, 直接查找几个 way 即可. way 中的 line 映射, 是一一对应的, 不能够随意破坏行的顺序. |
+
+
+
+
+n-way 说明一个 set 里有 n 个 line/block.
+
+在使用 N-Ways Set-Associative 时, 这是一种阵列的表现方式:
+
+
+一个组里有 N 行, 其实是 N 个 set, 但是 set 中的每一行与 main memory 分的 cache page 中的行数是一样的.
+
+ cache 首先被分为 M 个 Set, M 等于 1 时, 也就是 1 个 Set, 这时, 等同于 Direct-Associative.
+
+ N 等于 1 时, 也就是说 1 个 Way, 这时, 等同于 Full Mapped.
+
+ cache 的大小等于 cache_line_size * way_num * set_num
+
+
+
+
+可以把 cache 看成是一个 M 行 N 列的二维表格, 每一个单元格就是一个 cache line;
+每一行就是一个 set, 由横向的 N 个 cache line 构成
+每一列就是一个 way, 由纵向的 M 行 cache line 构成;
+
+这个 Cache 就是一个 N way
+
+当 M 为 1 时, 就是全关联 cache; 当 N 为 1 时,就是直接映射 cache.
+
+
+
+
+
+PA 地址的 cache 索引, 最低位是 word 的寻址, 之后是 way (cache line) 的寻址, 再之后才是 tag 的寻址;
+
+
+
+
+
+cache hier 的问题: 在不同的微架构中, L1 与 L2 的关系可以是 inclusive 的, 也可以是 exclusive 的,
+
+ inclusive cache: 相同的 data 可以存放在 Both L1 和 L2 中.
+
+ exclusive cache: 相同的 data 只能放在 L1 或者 L2 中, 不能同时存在.
+
+ 目前一般使用 inclusive cache 类型, 每次 cache miss, 可以从下一级的 cache 中寻找, load. 而 exclusive cache, 每次 cache miss, 只能去 main memory 中 load.
+
+ 但是 exclusive cache 比较节省 cache size.
+
+
+
+
+### cache block
+-------
+
+每个 cache 单元被称为 cache block/line 需要保存 address, data, status 等信息, 因此由 functional blocks, Data RAM, TAG RAM, Cache Controller 等组件组成.
+
+
+会根据 memory request 是否是 cacheable 的来进行 cache 的寻址操作.
+
+| 组件 | 功能 |
+|:---:|:---:|
+| Tag RAM | 存放部分物理地址信息, 可能包含虚拟地址信息, (VA 的 Cache 索引可以与 VA 的地址转换同时进行) |
+| Data RAM | data 段存放 cache line 中的数据, 大小通常为 32byte 或 64byte, 一个 bus 的 wrap 操作. |
+| status 段 | 存放 cache 的状态, 可以是 MOESI 等. |
+
+
+1. Cache Page, main memory 中被等大小的分为的 piece, 称为 cache pages. cache page 的大小, 不但与总的 cache size 有关, 与 cache 的 organization 也有关.
+2. Cache line, cache page 中更小的单元, cache 缓存的最小单位.
+
+
+# 4 参考资料
+-------
+
+| 编号 | 链接 | 描述 |
+|:---:|:----:|:---:|
+| 1 | [理解Memory Barrier(内存屏障)](https://blog.csdn.net/caoshangpa/article/details/78853919) | NA |
+
+
+
+* 本作品/博文 ( [AderStep-紫夜阑珊-青伶巷草 Copyright ©2013-2017](http://blog.csdn.net/gatieme) ), 由 [成坚(gatieme)](http://blog.csdn.net/gatieme) 创作.
+
+* 采用
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可. 欢迎转载、使用、重新发布, 但务必保留文章署名[成坚gatieme](http://blog.csdn.net/gatieme) ( 包含链接: http://blog.csdn.net/gatieme ), 不得用于商业目的.
+
+* 基于本文修改后的作品务必以相同的许可发布. 如有任何疑问, 请与我联系.
+
+* **转载请务必注明出处, 谢谢, 不胜感激**
+
diff --git a/study/arch/cache/Cache/cache-associativity.jpg b/study/arch/cache/Cache/cache-associativity.jpg
new file mode 100644
index 0000000..e5b78e5
Binary files /dev/null and b/study/arch/cache/Cache/cache-associativity.jpg differ
diff --git a/study/arch/cache/Cache/cache_read.png b/study/arch/cache/Cache/cache_read.png
new file mode 100644
index 0000000..3bb15ee
Binary files /dev/null and b/study/arch/cache/Cache/cache_read.png differ
diff --git a/study/kernel/00-DESCRIPTION/ARCH.md b/study/kernel/00-DESCRIPTION/ARCH.md
index 806e76d..8eb4bd3 100644
--- a/study/kernel/00-DESCRIPTION/ARCH.md
+++ b/study/kernel/00-DESCRIPTION/ARCH.md
@@ -213,8 +213,11 @@ SGX 旨在以硬件安全为强制性保障, 不依赖于固件和软件的安
-------
+
ARM & Linaro [Kernel versions highlights](https://developer.arm.com/tools-and-software/open-source-software/linux-kernel)
+ARM64 架构文档地址下载 [](https://developer.arm.com/architectures/cpu-architecture)
+
[Memory Layout on AArch64 Linux](https://www.kernel.org/doc/html/latest/arm64/memory.html)
@@ -438,7 +441,24 @@ SLS 被认为是 Spectre 漏洞的变体, 但二者的攻击范围略有不同,
[Linux Benchmark Suite Homepage](http://lbs.sourceforge.net)
-# 6 总线
+# 6 通用
+-------
+
+## 6.1 SYSCALL
+-------
+
+[remove in-kernel calls to syscalls 000/109](https://lore.kernel.org/all/20180329112426.23043-1-linux@dominikbrodowski.net)
+
+
+基于 pt_regs 传递 syscall 的参数, 防止在 syscall 的调用链中泄漏随机的用户提供的寄存器内容.
+
+| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
+|:----:|:----:|:---:|:----:|:---------:|:----:|
+| 2018/04/05 | Dominik Brodowski | [use struct pt_regs based syscall calling for x86-64](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=d5a00528b58cdb2c71206e18bd021e34c4eab878) | NA | v1 ☑ 4.17-rc1 | [LORE 0/7](https://lore.kernel.org/all/20180330093720.6780-1-linux@dominikbrodowski.net), [LORE v3,0/8](https://lore.kernel.org/all/20180405095307.3730-1-linux@dominikbrodowski.net) |
+| 2018/07/11 | Mark Rutland | [arm64: invoke syscalls with pt_regs](https://patchwork.kernel.org/project/linux-security-module/patch/20210212051500.943179-1-jiancai@google.com) | NA | v7 ☐ | [2021/06/10Patchwork v5,00/21](https://lore.kernel.org/lkml/20180711135656.20670-1-mark.rutland@arm.com) |
+
+
+# 7 总线
-------
FireBox: Warehouse-Scale Computers
diff --git a/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md b/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md
index 26c4e8f..52ecca2 100644
--- a/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md
+++ b/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md
@@ -4252,9 +4252,9 @@ ZONE_MOVABLE 一个 pseudo zone, 它实际是从内核划分的某个 zone 中
> 内核通过将已经将内存划分为许多具有不同特征的 ZONE, 来防止出现较严重的内存碎片, 特别是通过引入 ZONE_MOVABLE 专区, 通过隔离可移动和不可移动的分配请求(ZONE_MOVABLE 中区域, 只满足应该可以移动页面(或者简单地回收它们)来根据需要创建更大的区域).
-理想很美好, 显示很残酷, 仍然会有一些情况会破坏 ZONE_MOVABLE 想要的美好. 经常会有一些零碎的、位置不好的、当前无法被移动移动的页面而导致 ZONE_MOVABLE 的整块内存无法被移动.
-
+理想很美好, 现实很残酷, 仍然会有一些情况会破坏 ZONE_MOVABLE 想要的美好. 经常会有一些零碎的、位置不好的、当前无法被移动移动的页面固定在 ZONE_MOVABLE 中, 而导致 ZONE_MOVABLE 的整块内存无法被移动. 参见 [Preserving the mobility of ZONE_MOVABLE](https://lwn.net/Articles/843326)
+例如, 在设备执行 I/O 时就往往会 PIN 住一些页面, 此时移动页面往往会产生不幸的副作用. 通常, 这种固定持续时间很短, 往往不是一个大问题. 不过, 有时候这种固定可以持续很长时间ーー例如, 数周. 用于 RDMA 的内存缓冲区常常牵涉到这种反社会行为, 但是也有其他的例子. 当然, 一个实际上连续的用户空间缓冲区可能广泛分散在物理内存中, 因此长时间固定其中一个缓冲区可能会产生同样广泛分散的问题.
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|:----:|:----:|:---:|:----:|:---------:|:----:|
diff --git a/study/kernel/00-DESCRIPTION/SCHEDULER.md b/study/kernel/00-DESCRIPTION/SCHEDULER.md
index 6840416..1914108 100644
--- a/study/kernel/00-DESCRIPTION/SCHEDULER.md
+++ b/study/kernel/00-DESCRIPTION/SCHEDULER.md
@@ -1310,7 +1310,6 @@ ARM 的 Morten Rasmussen 一直致力于ANDROID 调度器优化的:
|:----:|:----:|:---:|:---:|:----------:|:----:|
| 2016/10/14 | Vincent Guittot | [sched: Clean-ups and asymmetric cpu capacity support](https://lore.kernel.org/patchwork/cover/725608) | 调度程序目前在非对称计算能力的系统上没有做太多的工作来提高性能(读ARM big.LITTLE). 本系列主要通过对任务唤醒路径进行一些调整来改善这种情况, 这些调整主要考虑唤醒时的计算容量, 而不仅仅考虑cpu对这些系统是否空闲. 在部分使用的场景中, 这为我们提供了一致的、可能更高的吞吐量. SMP的行为和性能应该是不受影响.
注意这组补丁是分批合入的 | v1 ☑ 4.10-rc1 | [PatchWork](https://lore.kernel.org/patchwork/cover/725608) |
| 2021/06/03 | Valentin Schneider | [Rework CPU capacity asymmetry detection](https://lore.kernel.org/patchwork/cover/1424708) | 当前版本 asym_cpu_capacity_level 存在几个问题.
1. 只能支持到最低的拓扑级别, 对全局的拓扑域不可见.
2. 不支持 NUMA 级别的异构, 因为初始化 NUMA 级别的 sd_numa_mask 中不包含其他 NODE, 最终 sched_domain_span 是在构建调度域的时候进行的更新的.
这对于大多数现有的不对称设计很实用, 但是却不支持普适的性能异构架构.这可能不是最好的方法, 在一些领域可能看不到任何不对称. 这对于不合适的迁移和能量感知的安置可能会有问题. 因此, 对于受影响的平台, 它可能导致对唤醒和 CPU 选择路径的自定义更改.
这组补丁修改了执行非对称检测的方式, 允许将非对称拓扑级别固定在最低的拓扑级别上, 在最低的拓扑级别上, 给定调度域中的所有 CPU 都可以看到整个 CPU 容量范围. asym_cpu_capacity_level 还将跟踪那些观察到任何非对称范围的级别, 以使用 SD_ASYM_CPUCAPACITY 标志表示相应的调度域, 并为这些域启用不匹配迁移. 为了区分局部和全范围 CPU 容量不对称的调度域, 引入了新的调度域标志: SD_ASYM_CPUCAPACITY_FULL. | v7 ☑ 5.14-rc1 | [PatchWork v1](https://lore.kernel.org/patchwork/cover/1414557)
*-*-*-*-*-*-*-*
[PatchWork v7](https://lore.kernel.org/all/20210603140627.8409-1-beata.michalska@arm.com) |
-| 2021/07/30 | Will Deacon | [Add support for 32-bit tasks on asymmetric AArch32 systems](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=702f43872665) | 一些体系结构, 特别是 ARM, 配置了一些 CPU 支持传统的 32 位应用程序, 但是一些 CPU 只支持 64 位. 这组补丁增加了对 32 位程序调度的支持, 这些 32 位的程序只能在支持传统 32 位任务的 CPU 中执行. | v1 ☑ [5.15-rc1](https://kernelnewbies.org/LinuxChanges#Linux_5.15.Support_for_asymmetric_scheduling_affinity) | [PatchWork v11,00/16](https://lore.kernel.org/all/20210730112443.23245-1-will@kernel.org) |
@@ -1413,6 +1412,46 @@ schedtune 与 uclamp 都是由 ARM 公司的 Patrick Bellasi 主导开发.
|:----:|:----:|:---:|:------:|:---:|
| 2016/02/23 | Steve Muckle 等 | [freezer,sched: Rewrite core freezer logic](https://lore.kernel.org/patchwork/cover/1444882) | 重写冻结的核心逻辑, 从而使得 WRT 解冻的表现更加合理. 通过将 PF_FROZEN 替换为 TASK_FROZEN (一种特殊的块状态), 可以确保冻结的任务保持冻结状态, 直到明确解冻, 并且不会像目前可能的那样过早随机唤醒. | v2 | [2021/06/01 RFC](https://lore.kernel.org/patchwork/cover/1439538)
*-*-*-*-*-*-*-*
[2021/06/01 RFC](https://lore.kernel.org/patchwork/cover/1444882) |
+## 7.6 异构
+-------
+
+
+
+随着不算的发展, 通用 CPU 上扩展了越来越多的指令集和功能, 但是这些功能并不一定所有场景都适用. 因此一类非对称系统 AMP 应运而生. 这些可能无法在所有 CPU 上提供相同级别的用户空间 ISA 支持, 这意味着某些应用程序无法由某些 CPU 执行. 已经有很多这样的例子:
+
+* arm64 big.LITTLE 设计不支持两个集群上的 32 位应用程序. 有些 CPU 支持 32 位应用, 有些 CPU 只支持 64 位应用.
+
+* Intel 第 12th 的的酷睿核 Alder Lake, P 核支持 AUX-512 指令, 但是 E 核却不支持.
+
+同样的结构可以推广到其他扩展指令, 比如 ARM64 的 SVE, SVE2 以及 SME2. 但是不局限于扩展指令的支持. 比如 SMT 等都可以适用到类似的异构架构.
+
+v5.15 合入的 [Add support for 32-bit tasks on asymmetric AArch32 systems](https://lore.kernel.org/all/20210730112443.23245-1-will@kernel.org) 就对 big.LITTLE 上不同 cluster 对 32 位应用支持不一做了感知.
+
+
+
+
+1. 通过 static_key arm64_mismatched_32bit_el0 来标记这类异构架构, system_32bit_el0_cpumask 标记了系统中支持 32 位应用程序的 cpumask.
+
+2. 为进程引入了 [task_cpu_possible_mask()](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d82158fa6df4237c9859b27d719c53b4fe09e69e) 来标记进程能运行的 cpumask. 对于系统中的 32 位程序来说, 就是 system_32bit_el0_cpumask. 同时进程中[新增 task_struct::user_cpus_ptr](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b90ca8badbd11488e5f762346b028666808164e7), 随后将 cpuset 和 cpu affinity 等都感知到了进程 affinity 的这些变更.
+
+3. 这种架构下, 执行 execve() 的 CPU 可能与新的应用程序映像不兼容(比如在不支持 32 位的应用的 CPU 上通过 execve() 执行了一个 32位的应用程序). 这种情况下, 需要限制任务的关联掩码, 并确保[在兼容的 CPU 上加载并启动](https://elixir.bootlin.com/linux/v5.15/source/arch/arm64/kernel/process.c#L608)新的程序镜像. 从用户空间的角度来看, 这看起来就像不兼容的 CPU 在任务的关联掩码中被热插拔一样. 类似地, 如果后续的 execve() 恢复为兼容映像, 则[旧的 CPU 亲和性就需要恢复](https://elixir.bootlin.com/linux/v5.15/source/arch/arm64/kernel/process.c#L610). 比如在不支持 32 位应用的系统上执行 32 位任务时, 则通过 [force_compatible_cpus_allowed_ptr()](https://elixir.bootlin.com/linux/v5.15/source/kernel/sched/core.c#L2919) 确保进程在能够实际运行它的 CPU 上启动. 类似地, 在这样的系统上再次执行 64 位任务时, 如果以前受到限制, 请尝试通过 [relax_compatible_cpus_allowed_ptr()](https://elixir.bootlin.com/linux/v5.15/source/kernel/sched/core.c#L2969) 从 user_cpus_ptr 恢复进程的 cpumask.
+
+4. 同时 [CPUHOTPLUG 也要做类似的修正](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=df950811f4a884d08f05e22a8e0089d54bb4ba70), 如果我们想支持 32 位应用程序, 但是在这种异构的系统中, 当我们确定了存在一个 CPU 不支持 32 位应用支持时, 我们必须确保系统始终拥有一个 online 的支持 32 位应用的 CPU. 这对于调度程序很重要, 如果没有支持 32 位 CPU 可用, 则由于 HOTPLUG 事件而导致的强制迁移将挂起. enable_mismatched_32bit_el0 中用 lucky_winner 标记了系统发现的一个支持 32为应用的 CPU, 将其 offline_disabled 设置为 true, 禁止其下线.
+
+5. 在 [sysfs 中提供 `/sys/devices/system/cpu/aarch32_el0`](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7af33504d1c8077b40121294b5eb6e680a859468), 向用户空间公布具有 32 位功能支持的 CPU 集 system_32bit_el0_cpumask(). 同时提供了一个内核启动参数 [allow_mismatched_32bit_el0 来开启](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ead7de462ae56b2d2e56fb5a414f6e916dddc4c9). 只有添加了该启动参数, [sysfs 接口](https://elixir.bootlin.com/linux/v5.15/source/arch/arm64/kernel/cpufeature.c#L1343)才会提供. HOTPLUG 也才会限制.
+
+6. 有了上述的支持, execve() 32 位的应用时进程可以自适应的运行在支持自己的 CPU 上. 而通过 hotplug 限制也保证系统肯定有支持 32 位应用的 CPU 处于 online 状态, 这样在只支持 64 位的 CPU 上运行 32 位应用的时候, 就不用[通过信号触发 kill 操作](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=94f9c00f6460c0b175226c8fe6fd137547b239bd), 杀掉应用了.
+
+
+| 参数选项 | 描述 |
+|:------:|:----:|
+| allow_mismatched_32bit_el0 | 只有添加了该启动参数, 内核才支持 32 位应用的自动感知, [sysfs 接口](https://elixir.bootlin.com/linux/v5.15/source/arch/arm64/kernel/cpufeature.c#L1343)才会提供. HOTPLUG 也才会限制. 然后 init_32bit_el0_mask 的时候, 才会注册 CPUHP_AP_ONLINE_DYN 接口的 cpuhp, 才会通过 enable_mismatched_32bit_el0() 进行一系列初始化操作. |
+| arm64_mismatched_32bit_el0 | 如果 allow_mismatched_32bit_el0 开启了, 且系统在对 CPU 检查 enable_mismatched_32bit_el0() 支持的时候, 发现 CPU 支持 32 位应用, 则会是使能该 static key. 同时将 cpu_32bit_el0_mask 标记那些支持 32 位应用的 cpumask. 同时 arch_setup_new_exec() 才会针对是否是在运行 32 位应用自动进行放缩. |
+
+
+| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
+|:----:|:----:|:---:|:---:|:----------:|:----:|
+| 2021/07/30 | Will Deacon | [Add support for 32-bit tasks on asymmetric AArch32 systems](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=702f43872665) | 一些体系结构, 特别是 ARM, 配置了一些 CPU 支持传统的 32 位应用程序, 但是一些 CPU 只支持 64 位. 这组补丁增加了对 32 位程序调度的支持, 这些 32 位的程序只能在支持传统 32 位任务的 CPU 中执行. | v1 ☑ [5.15-rc1](https://kernelnewbies.org/LinuxChanges#Linux_5.15.Support_for_asymmetric_scheduling_affinity) | [PatchWork v11,00/16](https://lore.kernel.org/all/20210730112443.23245-1-will@kernel.org) |
# 8 实时性 linux PREEMPT_RT