更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_vm_filemap.h
浏览该文件的文档.
1/*!
2 * @file los_vm_filemap.h
3 * @brief
4 * @link
5 @verbatim
6 磁盘高速缓存是一种软件机制,它允许系统把通常存放在磁盘上的一些数据保留在 RAM 中,以便对那些数据的
7 进一步访问不用再访问磁盘而能尽快得到满足。
8 页高速缓存中的信息单位是一个完整的页。
9 一个页包含的磁盘块在物理上不一定相邻,所以不能用设备号和块号标识,而是通过页的所有者和所有者数据中的索引来识别。
10 页高速缓存可以缓存以下内容
11 A.普通文件数据
12 B.含有目录的页
13 C.直接从快设备读取的页
14 D.用户进程数据的页
15 E.特殊文件系统的文件页
16 @endverbatim
17 * @version
18 * @author weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
19 * @date 2021-12-9
20 */
21/*
22 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
23 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
24 *
25 * Redistribution and use in source and binary forms, with or without modification,
26 * are permitted provided that the following conditions are met:
27 *
28 * 1. Redistributions of source code must retain the above copyright notice, this list of
29 * conditions and the following disclaimer.
30 *
31 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
32 * of conditions and the following disclaimer in the documentation and/or other materials
33 * provided with the distribution.
34 *
35 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
36 * to endorse or promote products derived from this software without specific prior written
37 * permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
40 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
41 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
43 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
45 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
46 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
47 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
49 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51
52/**
53 * @defgroup los_vm_filemap vm filemap definition
54 * @ingroup kernel
55 */
56
57#ifndef __LOS_VM_FILEMAP_H__
58#define __LOS_VM_FILEMAP_H__
59
60#ifdef LOSCFG_FS_VFS
61#include "fs/file.h"
62#endif
63#include "los_vm_map.h"
64#include "los_vm_page.h"
65#include "los_vm_common.h"
66#include "los_vm_phys.h"
67
68#ifdef __cplusplus
69#if __cplusplus
70extern "C" {
71#endif /* __cplusplus */
72#endif /* __cplusplus */
73
74#if 0 //@note_#if0
75//page_mapping描述的是一个文件在内存中被映射了多少页,<文件,文件页的关系>
76/* file mapped in VMM pages */
77struct page_mapping {//记录文件页和文件关系的结构体,叫文件页映射
78 LOS_DL_LIST page_list; /* all pages | 链表上挂的是属于该文件的所有FilePage,这些页的内容都来源同一个文件*/
79 SPIN_LOCK_S list_lock; /* lock protecting it | 操作page_list的自旋锁*/
80 LosMux mux_lock; /* mutex lock | 操作page_mapping的互斥量*/
81 unsigned long nrpages; /* number of total pages |page_list的节点数量 */
82 unsigned long flags; ///< @note_why 全量代码中也没查到源码中对其操作
83 Atomic ref; /* reference counting | 引用次数(自增/自减),对应add_mapping/dec_mapping*/
84 struct Vnode *host; /* owner of this mapping | 属于哪个文件的映射*/
85};
86
87
88/* map: full_path(owner) <-> mapping */ //叫文件映射
89struct file_map { //为在内核层面文件在内存的身份证,每个需映射到内存的文件必须创建一个file_map,都挂到全局g_file_mapping链表上
90 LOS_DL_LIST head; ///< 链表节点,用于挂到g_file_mapping上
91 LosMux lock; /* lock to protect this mapping */
92 struct page_mapping mapping; ///< 每个文件都有唯一的page_mapping标识其在内存的身份
93 char *owner; /* owner: full path of file | 文件全路径来标识唯一性*/
94};
95
96#endif
97
98/// 文件页结构体
99typedef struct FilePage {
100 LOS_DL_LIST node; ///< 节点,节点挂到page_mapping.page_list上,链表以 pgoff 从小到大方式排序.
101 LOS_DL_LIST lru; ///< lru节点, 结合 LosVmPhysSeg: LOS_DL_LIST lruList[VM_NR_LRU_LISTS] 理解
102 LOS_DL_LIST i_mmap; /* list of mappings | 链表记录文件页被哪些进程映射 MapInfo.node挂上来*/
103 UINT32 n_maps; /* num of mapping | 记录被进程映射的次数*/
104 struct VmPhysSeg *physSeg; /* physical memory that file page belongs to | 物理段:物理页框 = 1:N */
105 struct VmPage *vmPage; ///< 物理页框
106 struct page_mapping *mapping; ///< 此结构由文件系统提供,用于描述装入点 见于 ..\third_party\NuttX\include\nuttx\fs\fs.h
107 VM_OFFSET_T pgoff; ///< 页标,文件被切成一页一页读到内存
108 UINT32 flags; ///< 标签
109 UINT16 dirtyOff; ///< 脏页的页内偏移地址
110 UINT16 dirtyEnd; ///< 脏页的结束位置
112/// 虚拟地址和文件页的映射信息,在一个进程使用文件页之前,需要提前做好文件页在此内存空间的映射关系,如此通过虚拟内存就可以对文件页读写操作.
113typedef struct MapInfo {
114 LOS_DL_LIST node; ///< 节点,挂到page->i_mmap链表上.链表上记录要操作文件页的进程对这个page的映射信息
115 VADDR_T vaddr; ///< 虚拟地址.每个进程访问同一个文件页的虚拟地址都是不一样的
116 LosFilePage *page; ///< 文件页中只记录物理地址,是不会变的.但它是需要被多个进程访问,和映射的.
117 LosArchMmu *archMmu; ///< mmu完成vaddr和page->vmPage->physAddr物理地址的映射
119/// Flags由 bitmap 管理
121 FILE_PAGE_FREE, ///< 空闲页
122 FILE_PAGE_LOCKED, ///< 被锁页
123 FILE_PAGE_REFERENCED, ///< 被引用页
124 FILE_PAGE_DIRTY, ///< 脏页
125 FILE_PAGE_LRU, ///< LRU置换页
126 FILE_PAGE_ACTIVE, ///< 活动页
127 FILE_PAGE_SHARED, ///< 共享页
128};
129
130#define PGOFF_MAX 2000
131#define MAX_SHRINK_PAGECACHE_TRY 2
132#define VM_FILEMAP_MAX_SCAN (SYS_MEM_SIZE_DEFAULT >> PAGE_SHIFT) ///< 扫描文件映射页最大数量
133#define VM_FILEMAP_MIN_SCAN 32 ///< 扫描文件映射页最小数量
134/// 给页面贴上被锁的标签
135STATIC INLINE VOID OsSetPageLocked(LosVmPage *page)
136{
138}
139/// 给页面撕掉被锁的标签
140STATIC INLINE VOID OsCleanPageLocked(LosVmPage *page)
141{
143}
144/// 给页面贴上数据被修改的标签
145STATIC INLINE VOID OsSetPageDirty(LosVmPage *page)
146{
148}
149/// 给页面撕掉数据被修改的标签
150STATIC INLINE VOID OsCleanPageDirty(LosVmPage *page)
151{
153}
154/// 给页面贴上活动的标签
155STATIC INLINE VOID OsSetPageActive(LosVmPage *page)
156{
158}
159/// 给页面撕掉活动的标签
160STATIC INLINE VOID OsCleanPageActive(LosVmPage *page)
161{
163}
164/// 给页面贴上置换页的标签
165STATIC INLINE VOID OsSetPageLRU(LosVmPage *page)
166{
168}
169/// 给页面贴上被释放的标签
170STATIC INLINE VOID OsSetPageFree(LosVmPage *page)
171{
173}
174/// 给页面撕掉被释放的标签
175STATIC INLINE VOID OsCleanPageFree(LosVmPage *page)
176{
178}
179/// 给页面贴上被引用的标签
180STATIC INLINE VOID OsSetPageReferenced(LosVmPage *page)
181{
183}
184/// 给页面撕掉被引用的标签
185STATIC INLINE VOID OsCleanPageReferenced(LosVmPage *page)
186{
188}
189/// 页面是否活动
190STATIC INLINE BOOL OsIsPageActive(LosVmPage *page)
191{
192 return BIT_GET(page->flags, FILE_PAGE_ACTIVE);
193}
194/// 页面是否被锁
195STATIC INLINE BOOL OsIsPageLocked(LosVmPage *page)
196{
197 return BIT_GET(page->flags, FILE_PAGE_LOCKED);
198}
199/// 页面是否被引用,只被一个进程引用的页叫私有页,多个进程引用就是共享页,此为共享内存的本质所在
201{
202 return BIT_GET(page->flags, FILE_PAGE_REFERENCED);
203}
204/// 页面是否为脏页,所谓脏页就是页内数据是否被更新过,只有脏页才会有写时拷贝
205STATIC INLINE BOOL OsIsPageDirty(LosVmPage *page)
206{
207 return BIT_GET(page->flags, FILE_PAGE_DIRTY);
208}
209/// 文件页是否映射过了
210STATIC INLINE BOOL OsIsPageMapped(LosFilePage *page)
211{
212 return (page->n_maps != 0);//由映射的次数来判断
213}
214
215/*! The follow three functions is used to SHM module | 给页面贴上共享页标签*/
216STATIC INLINE VOID OsSetPageShared(LosVmPage *page)
217{
218 LOS_BitmapSet(&page->flags, FILE_PAGE_SHARED);//设为共享页面,共享页位 置0
219}
220/// 给页面撕掉共享页标签
221STATIC INLINE VOID OsCleanPageShared(LosVmPage *page)
222{
223 LOS_BitmapClr(&page->flags, FILE_PAGE_SHARED);//共享页位 置0
224}
225/// 是否为共享页
226STATIC INLINE BOOL OsIsPageShared(LosVmPage *page)
227{
228 return BIT_GET(page->flags, FILE_PAGE_SHARED);
229}
230
231typedef struct ProcessCB LosProcessCB;
232
233#ifdef LOSCFG_FS_VFS
234INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region);
235STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region);
236VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB);
237#endif
238
240LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff);
241LosMapInfo *OsGetMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr);
242VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr);
243VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *pgFault, BOOL cleanDirty);
244VOID OsFileCacheFlush(struct page_mapping *mapping);
245VOID OsFileCacheRemove(struct page_mapping *mapping);
246VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info);
247VOID OsUnmapAllLocked(LosFilePage *page);
248VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType);
249VOID OsLruCacheDel(LosFilePage *fpage);
255int OsTryShrinkMemory(size_t nPage);
256VOID OsMarkPageDirty(LosFilePage *fpage, LosVmMapRegion *region, int off, int len);
257
258#ifdef LOSCFG_DEBUG_VERSION
259VOID ResetPageCacheHitInfo(int *try, int *hit);
260struct file_map* GetFileMappingList(void);
261#endif
262#ifdef __cplusplus
263#if __cplusplus
264}
265#endif /* __cplusplus */
266#endif /* __cplusplus */
267
268#endif /* __LOS_VM_FILEMAP_H__ */
269
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
对状态字的某一标志位进行置1操作
Definition: los_bitmap.c:60
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
对状态字的某一标志位进行清0操作
Definition: los_bitmap.c:69
volatile INT32 Atomic
Definition: los_atomic.h:102
unsigned short UINT16
Definition: los_typedef.h:56
signed int INT32
Definition: los_typedef.h:60
unsigned long VADDR_T
Definition: los_typedef.h:208
unsigned long VM_OFFSET_T
Definition: los_typedef.h:212
int STATUS_T
Definition: los_typedef.h:215
unsigned int UINT32
Definition: los_typedef.h:57
size_t BOOL
Definition: los_typedef.h:88
STATIC INLINE VOID OsSetPageActive(LosVmPage *page)
给页面贴上活动的标签
VOID OsDeletePageCacheLru(LosFilePage *page)
删除页高速缓存和LRU,对应 OsAddToPageacheLru
OsPageFlags
Flags由 bitmap 管理
@ FILE_PAGE_FREE
空闲页
@ FILE_PAGE_REFERENCED
被引用页
@ FILE_PAGE_DIRTY
脏页
@ FILE_PAGE_LOCKED
被锁页
@ FILE_PAGE_LRU
LRU置换页
@ FILE_PAGE_SHARED
共享页
@ FILE_PAGE_ACTIVE
活动页
VOID OsPageRefDecNoLock(LosFilePage *page)
Definition: los_vm_scan.c:189
STATIC INLINE VOID OsSetPageFree(LosVmPage *page)
给页面贴上被释放的标签
LosMapInfo * OsGetMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr)
通过虚拟地址获取文件页映射信息,archMmu每个进程都有属于自己的mmu
VOID OsFileCacheFlush(struct page_mapping *mapping)
文件缓存冲洗,把所有fpage冲洗一边,把脏页洗到dirtyList中,配合OsFileCacheRemove理解
VOID OsPageRefIncLocked(LosFilePage *page)
Definition: los_vm_scan.c:145
VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType)
Definition: los_vm_scan.c:69
VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr)
STATIC INLINE VOID OsCleanPageReferenced(LosVmPage *page)
给页面撕掉被引用的标签
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
STATIC INLINE VOID OsCleanPageDirty(LosVmPage *page)
给页面撕掉数据被修改的标签
VOID OsMarkPageDirty(LosFilePage *fpage, LosVmMapRegion *region, int off, int len)
STATIC INLINE VOID OsCleanPageFree(LosVmPage *page)
给页面撕掉被释放的标签
STATIC INLINE VOID OsSetPageLRU(LosVmPage *page)
给页面贴上置换页的标签
struct file_map * GetFileMappingList(void)
STATIC INLINE VOID OsCleanPageLocked(LosVmPage *page)
给页面撕掉被锁的标签
STATIC INLINE VOID OsSetPageDirty(LosVmPage *page)
给页面贴上数据被修改的标签
VOID OsUnmapAllLocked(LosFilePage *page)
解除文件页在所有进程的映射
Definition: los_vm_scan.c:57
VOID OsLruCacheDel(LosFilePage *fpage)
Definition: los_vm_scan.c:85
VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB)
VOID OsDoFlushDirtyPage(LosFilePage *fpage)
冲洗脏页数据,将脏页数据回写磁盘
STATIC INLINE VOID OsCleanPageShared(LosVmPage *page)
给页面撕掉共享页标签
STATIC INLINE BOOL OsIsPageMapped(LosFilePage *page)
文件页是否映射过了
STATIC INLINE BOOL OsIsPageActive(LosVmPage *page)
页面是否活动
STATIC INLINE BOOL OsIsPageDirty(LosVmPage *page)
页面是否为脏页,所谓脏页就是页内数据是否被更新过,只有脏页才会有写时拷贝
LosFilePage * OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff)
struct FilePage LosFilePage
文件页结构体
VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info)
Definition: los_vm_scan.c:44
STATIC INLINE BOOL OsIsPageShared(LosVmPage *page)
是否为共享页
int OsTryShrinkMemory(size_t nPage)
Definition: los_vm_scan.c:340
VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *pgFault, BOOL cleanDirty)
删除映射信息
STATIC INLINE VOID OsSetPageShared(LosVmPage *page)
STATIC INLINE VOID OsSetPageLocked(LosVmPage *page)
给页面贴上被锁的标签
VOID ResetPageCacheHitInfo(int *try, int *hit)
STATIC INLINE BOOL OsIsPageReferenced(LosVmPage *page)
页面是否被引用,只被一个进程引用的页叫私有页,多个进程引用就是共享页,此为共享内存的本质所在
VOID OsFileCacheRemove(struct page_mapping *mapping)
struct MapInfo LosMapInfo
虚拟地址和文件页的映射信息,在一个进程使用文件页之前,需要提前做好文件页在此内存空间的映射关系,如此通过虚拟内存就可以对文件页读写操作.
STATIC INLINE VOID OsSetPageReferenced(LosVmPage *page)
给页面贴上被引用的标签
STATIC INLINE VOID OsCleanPageActive(LosVmPage *page)
给页面撕掉活动的标签
LosFilePage * OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
STATIC INLINE BOOL OsIsPageLocked(LosVmPage *page)
页面是否被锁
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
LosFilePage * OsDumpDirtyPage(LosFilePage *oldPage)
备份脏页,老脏页撕掉脏页标签
OsLruList
Lru全称是Least Recently Used,即最近最久未使用的意思 针对匿名页和文件页各拆成对应链表。
Definition: los_vm_phys.h:74
内存管理单元(英语:memory management unit,缩写为MMU),有时称作分页内存管理单元(英语:paged memory management unit,缩写为PMMU)。
Definition: los_arch_mmu.h:86
文件页结构体
LOS_DL_LIST i_mmap
LOS_DL_LIST lru
lru节点, 结合 LosVmPhysSeg: LOS_DL_LIST lruList[VM_NR_LRU_LISTS] 理解
struct VmPage * vmPage
物理页框
UINT32 n_maps
struct VmPhysSeg * physSeg
UINT16 dirtyOff
脏页的页内偏移地址
VM_OFFSET_T pgoff
页标,文件被切成一页一页读到内存
struct page_mapping * mapping
此结构由文件系统提供,用于描述装入点 见于 ..\third_party\NuttX\fs\fs.h
LOS_DL_LIST node
节点,节点挂到page_mapping.page_list上,链表以 pgoff 从小到大方式排序.
UINT16 dirtyEnd
脏页的结束位置
UINT32 flags
标签
虚拟地址和文件页的映射信息,在一个进程使用文件页之前,需要提前做好文件页在此内存空间的映射关系,如此通过虚拟内存就可以对文件页读写操作.
LosFilePage * page
文件页中只记录物理地址,是不会变的.但它是需要被多个进程访问,和映射的.
VADDR_T vaddr
虚拟地址.每个进程访问同一个文件页的虚拟地址都是不一样的
LosArchMmu * archMmu
mmu完成vaddr和page->vmPage->physAddr物理地址的映射
LOS_DL_LIST node
节点,挂到page->i_mmap链表上.链表上记录要操作文件页的进程对这个page的映射信息
Definition: los_mux.h:73
缺页结构信息体
Definition: los_vm_map.h:95
物理页框描述符 虚拟内存体现的是程序对内存资源的需求,而物理内存是对该请求的供应。 伙伴算法的思想是:把内存中连续的空闲页框空间看成是空闲页框块,并按照它们的大小(连续页框的数目)分组
Definition: los_vm_page.h:53
UINT32 flags
Definition: los_vm_page.h:58
物理段描述符
Definition: los_vm_phys.h:85
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
struct page_mapping mapping
每个文件都有唯一的page_mapping标识其在内存的身份
char * owner
LOS_DL_LIST head
链表节点,用于挂到g_file_mapping上
unsigned long nrpages
SPIN_LOCK_S list_lock
LOS_DL_LIST page_list
unsigned long flags
@note_why 全量代码中也没查到源码中对其操作
struct Vnode * host