From 0db46440704831d345b8297f8bc60972217c0a7d Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 13:47:38 +0800 Subject: [PATCH 1/5] riscv-sparsemem: commit correct result of tinycorrect-spaces Signed-off-by: Wu Zhangjin --- articles/20220410-riscv-sparsemem.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/articles/20220410-riscv-sparsemem.md b/articles/20220410-riscv-sparsemem.md index ba839f4..04b7189 100644 --- a/articles/20220410-riscv-sparsemem.md +++ b/articles/20220410-riscv-sparsemem.md @@ -1,3 +1,4 @@ +> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces]
> Author: Jack Y.
> Date: 2022/04/10
> Revisor: Falcon
@@ -31,7 +32,7 @@ Linux 最早采用的是简单直接的 FLATMEM 模型,从名字可以看出 从 PFN 到 `struct page` 的地址,只需在 `struct page` 数组的基地址 `mem_map` 的基础上,加上 PFN(再减去体系结构定义的偏移量 `ARCH_PFN_OFFSET`,以适配不从 0x0 地址开始的物理空间)即可;而从 `struct page` 的地址到 PFN 也仅仅是把上述公式进行一下移项变换而已。FLATMEM 模型的 `struct page` 结构如下图所示: -![](images/riscv_sparsemem/FLATMEM.png) +![](images/riscv_sparsemem/FLATMEM.png) FLATMEM 模型的优点是结构简单,而且 `pfn_to_page()` 和 `page_to_pfn()` 只需进行两次加减法运算,十分高效。 @@ -86,7 +87,7 @@ struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] 由于在经典 SPARSEMEM 模型中, `SECTIONS_PER_ROOT` 被定义为 1,`mem_section` 二维数组实际上就是长度为 `NR_MEM_SECTIONS` 的一维数组。经典 SPARSEMEM 模型中 `struct mem_section` 的组织结构如下: -![](images/riscv_sparsemem/classic_sparsemem.png) +![](images/riscv_sparsemem/classic_sparsemem.png) 每一个 `struct mem_section` 都有一个编号,叫做 `section_nr`,定义方式为物理地址右移 `PA_SECTION_SHIFT` 位,可以轻易理解的是,`PA_SECTION_SHIFT` 的值就等于 `SECTION_SIZE_BITS`。 @@ -290,7 +291,7 @@ static int __meminit sparse_index_init(unsigned long section_nr, int nid) 下图是 SPARSEMEM_EXTREME 扩展的 `struct mem_section` 组织结构,在图中下标为 $1$ 的 MEM_SECTION_ROOT 中无任何物理内存与其对应,即可不分配相应的 `struct mem_section` 结构体。 -![](images/riscv_sparsemem/SPARSEMEM_EXTREME.png) +![](images/riscv_sparsemem/SPARSEMEM_EXTREME.png) ## SPARSEMEM_VMEMMAP 扩展 @@ -339,6 +340,6 @@ SPARSEMEM_VMEMMAP 扩展是为了解决上文中提到的经典 SPARSEMEM 模型 ## 参考文档 -1.[Memory: the flat, the discontiguous, and the sparse](https://lwn.net/Articles/789304/) -2.[从 pfn_to_page/page_to_pfn 看 Linux SPARSEMEM 内存模型](https://www.cnblogs.com/liuhailong0112/p/14515466.html) -3.[Remove DISCINTIGMEM memory model](https://lwn.net/Articles/858333/) \ No newline at end of file +1.[Memory: the flat, the discontiguous, and the sparse](https://lwn.net/Articles/789304/) +2.[从 pfn_to_page/page_to_pfn 看 Linux SPARSEMEM 内存模型](https://www.cnblogs.com/liuhailong0112/p/14515466.html) +3.[Remove DISCINTIGMEM memory model](https://lwn.net/Articles/858333/) -- Gitee From 7e8fd739b1de13fe42eaaec008ee050335e233e1 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 14:27:52 +0800 Subject: [PATCH 2/5] riscv-sparsemem: commit correct result of tinycorrect-codeinline Signed-off-by: Wu Zhangjin --- articles/20220410-riscv-sparsemem.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/20220410-riscv-sparsemem.md b/articles/20220410-riscv-sparsemem.md index 04b7189..7637267 100644 --- a/articles/20220410-riscv-sparsemem.md +++ b/articles/20220410-riscv-sparsemem.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [comments codeinline]
> Author: Jack Y.
> Date: 2022/04/10
> Revisor: Falcon
@@ -85,7 +85,7 @@ struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] ____cacheline_internodealigned_in_smp; ``` -由于在经典 SPARSEMEM 模型中, `SECTIONS_PER_ROOT` 被定义为 1,`mem_section` 二维数组实际上就是长度为 `NR_MEM_SECTIONS` 的一维数组。经典 SPARSEMEM 模型中 `struct mem_section` 的组织结构如下: +由于在经典 SPARSEMEM 模型中,`SECTIONS_PER_ROOT` 被定义为 1,`mem_section` 二维数组实际上就是长度为 `NR_MEM_SECTIONS` 的一维数组。经典 SPARSEMEM 模型中 `struct mem_section` 的组织结构如下: ![](images/riscv_sparsemem/classic_sparsemem.png) -- Gitee From ed1dbbb443aded0b95b4b51395cc98e0bc4e322a Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 14:27:56 +0800 Subject: [PATCH 3/5] riscv-sparsemem: commit correct result of tinycorrect-images Signed-off-by: Wu Zhangjin --- articles/20220410-riscv-sparsemem.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/articles/20220410-riscv-sparsemem.md b/articles/20220410-riscv-sparsemem.md index 7637267..c081a4d 100644 --- a/articles/20220410-riscv-sparsemem.md +++ b/articles/20220410-riscv-sparsemem.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [comments codeinline]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [comments codeinline images]
> Author: Jack Y.
> Date: 2022/04/10
> Revisor: Falcon
@@ -32,7 +32,7 @@ Linux 最早采用的是简单直接的 FLATMEM 模型,从名字可以看出 从 PFN 到 `struct page` 的地址,只需在 `struct page` 数组的基地址 `mem_map` 的基础上,加上 PFN(再减去体系结构定义的偏移量 `ARCH_PFN_OFFSET`,以适配不从 0x0 地址开始的物理空间)即可;而从 `struct page` 的地址到 PFN 也仅仅是把上述公式进行一下移项变换而已。FLATMEM 模型的 `struct page` 结构如下图所示: -![](images/riscv_sparsemem/FLATMEM.png) +![FLATMEM.png](images/riscv_sparsemem/FLATMEM.png) FLATMEM 模型的优点是结构简单,而且 `pfn_to_page()` 和 `page_to_pfn()` 只需进行两次加减法运算,十分高效。 @@ -87,7 +87,7 @@ struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] 由于在经典 SPARSEMEM 模型中,`SECTIONS_PER_ROOT` 被定义为 1,`mem_section` 二维数组实际上就是长度为 `NR_MEM_SECTIONS` 的一维数组。经典 SPARSEMEM 模型中 `struct mem_section` 的组织结构如下: -![](images/riscv_sparsemem/classic_sparsemem.png) +![classic_sparsemem.png](images/riscv_sparsemem/classic_sparsemem.png) 每一个 `struct mem_section` 都有一个编号,叫做 `section_nr`,定义方式为物理地址右移 `PA_SECTION_SHIFT` 位,可以轻易理解的是,`PA_SECTION_SHIFT` 的值就等于 `SECTION_SIZE_BITS`。 @@ -291,7 +291,7 @@ static int __meminit sparse_index_init(unsigned long section_nr, int nid) 下图是 SPARSEMEM_EXTREME 扩展的 `struct mem_section` 组织结构,在图中下标为 $1$ 的 MEM_SECTION_ROOT 中无任何物理内存与其对应,即可不分配相应的 `struct mem_section` 结构体。 -![](images/riscv_sparsemem/SPARSEMEM_EXTREME.png) +![SPARSEMEM_EXTREME.png](images/riscv_sparsemem/SPARSEMEM_EXTREME.png) ## SPARSEMEM_VMEMMAP 扩展 -- Gitee From ab1285ae1517621a0d9e0660a434bc0da17a39a8 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 14:28:33 +0800 Subject: [PATCH 4/5] riscv-sparsemem: commit correct result of tinycorrect-urls Signed-off-by: Wu Zhangjin --- articles/20220410-riscv-sparsemem.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/articles/20220410-riscv-sparsemem.md b/articles/20220410-riscv-sparsemem.md index c081a4d..215f20f 100644 --- a/articles/20220410-riscv-sparsemem.md +++ b/articles/20220410-riscv-sparsemem.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [comments codeinline images]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [comments codeinline images urls]
> Author: Jack Y.
> Date: 2022/04/10
> Revisor: Falcon
@@ -13,7 +13,7 @@ 学习过操作系统课程的同学都知道,Linux 把 RAM 空间分成大小相同的页帧(Page Frame),Page Frame 是 Linux 内存管理的基本单位,在大多数情况下一般把一页的大小配置为 4 KB。每个页帧对应着一个「页帧号」(Page Frame Number,简称 PFN)。只要得知该页帧的 PFN,就能得知该页帧的物理地址,即可在硬件 RAM 上对这个地址对应的内存空间进行访问。 -而为了对一个页帧进行管理,Linux 设计了 `struct page` 这个结构体,该结构体中包括了该页的状态标志位、映射的地址空间、引用计数等内容,具体可参考[这篇文章](http://linux.laoqinren.net/kernel/memory-page/)。 +而为了对一个页帧进行管理,Linux 设计了 `struct page` 这个结构体,该结构体中包括了该页的状态标志位、映射的地址空间、引用计数等内容,具体可参考[这篇文章][001]。 物理内存的每一个页帧,都有一个对应的 `struct page` 结构体,而如何将这些结构体进行有效地组织和管理,就是 Linux 物理内存模型。更加通俗的来说,物理内存模型主要的作用是完成 PFN 和 `struct page` 之间的相互查找,即 `pfn_to_page()` 和 `page_to_pfn()`。 @@ -340,6 +340,11 @@ SPARSEMEM_VMEMMAP 扩展是为了解决上文中提到的经典 SPARSEMEM 模型 ## 参考文档 -1.[Memory: the flat, the discontiguous, and the sparse](https://lwn.net/Articles/789304/) -2.[从 pfn_to_page/page_to_pfn 看 Linux SPARSEMEM 内存模型](https://www.cnblogs.com/liuhailong0112/p/14515466.html) -3.[Remove DISCINTIGMEM memory model](https://lwn.net/Articles/858333/) +1. [Memory: the flat, the discontiguous, and the sparse][002] +2. [从 pfn_to_page/page_to_pfn 看 Linux SPARSEMEM 内存模型][004] +3. [Remove DISCINTIGMEM memory model][003] + +[001]: http://linux.laoqinren.net/kernel/memory-page/ +[002]: https://lwn.net/Articles/789304/ +[003]: https://lwn.net/Articles/858333/ +[004]: https://www.cnblogs.com/liuhailong0112/p/14515466.html -- Gitee From ac3d0581767cfef0456dc64ecfe4041029f6345b Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 14:29:15 +0800 Subject: [PATCH 5/5] riscv-sparsemem: commit correct result of tinycorrect-pangu Signed-off-by: Wu Zhangjin --- articles/20220410-riscv-sparsemem.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/articles/20220410-riscv-sparsemem.md b/articles/20220410-riscv-sparsemem.md index 215f20f..faf39f0 100644 --- a/articles/20220410-riscv-sparsemem.md +++ b/articles/20220410-riscv-sparsemem.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [comments codeinline images urls]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [comments codeinline images urls pangu]
> Author: Jack Y.
> Date: 2022/04/10
> Revisor: Falcon
@@ -50,7 +50,7 @@ SPARSEMEM 模型在当时被称为「一个新的、实验性的 DISCONTIGMEM 在 SPARSEMEM 模型中,设计了一个比 page 更大的内存管理粒度「mem_section」。 -一个 `mem_section` 所对应的内存大小由宏 `SECTION_SIZE_BITS` 定义。在 RISC-V 中,其被定义为 27(见arch/riscv/include/asm/sparsemem.h),即一个 `mem_section` 对应 $2^{27} = 128 $ MB 物理内存。 +一个 `mem_section` 所对应的内存大小由宏 `SECTION_SIZE_BITS` 定义。在 RISC-V 中,其被定义为 27(见 arch/riscv/include/asm/sparsemem.h),即一个 `mem_section` 对应 $2^{27} = 128 $ MB 物理内存。 而 SPARSEMEM 的总共数量则由宏 `NR_MEM_SECTIONS` 来定义,后者的定义整理如下: @@ -201,7 +201,7 @@ SPARSEMEM 模型设计了 `struct mem_section` 这样一个层级,将 FLATMEM 但经典 SPARSEMEM 模型仍有两大问题: 1. 经典 SPARSEMEM 模型的 `mem_section` 数组是固定分配的,在 RV32 架构下,共 128 个,这样的开销还可以接受;但在 RV64 架构下,其数量达到 $2^{29} = 536,870,912$ 个,实在是浪费空间十分严重。 -2. 尽管已经做了非常「巧妙」的编码,经典 SPARSEMEM 模型的 `pfn_to_page()` 和 `page_to_pfn()` 与 FLATMEM相比,仍然较为复杂。就 `pfn_to_page()` 来说,前者需要 2 次加法操作、1 次移位操作、1 次按位与操作和 1 次内存读取操作;而后者只需 1 次加法操作和 1 次减法操作即可。 +2. 尽管已经做了非常「巧妙」的编码,经典 SPARSEMEM 模型的 `pfn_to_page()` 和 `page_to_pfn()` 与 FLATMEM 相比,仍然较为复杂。就 `pfn_to_page()` 来说,前者需要 2 次加法操作、1 次移位操作、1 次按位与操作和 1 次内存读取操作;而后者只需 1 次加法操作和 1 次减法操作即可。 因此后续又增加了 SPARSEMEM 模型的两个扩展版本:SPARSEMEM_EXTREME 和 SPARSEMEM_VMEMMAP。 -- Gitee