• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @defgroup los_vm_filemap vm filemap definition
34  * @ingroup kernel
35  */
36 
37 #include "los_vm_filemap.h"
38 #include "los_vm_page.h"
39 #include "los_vm_phys.h"
40 #include "los_vm_common.h"
41 #include "los_vm_fault.h"
42 #include "los_process_pri.h"
43 #include "los_vm_lock.h"
44 #ifdef LOSCFG_FS_VFS
45 #include "vnode.h"
46 #endif
47 
48 #ifndef UNUSED
49 #define UNUSED(x)          (VOID)(x)
50 #endif
51 
52 #ifdef LOSCFG_DEBUG_VERSION
53 static int g_totalPageCacheTry = 0;
54 static int g_totalPageCacheHit = 0;
55 #define TRACE_TRY_CACHE() do { g_totalPageCacheTry++; } while (0)
56 #define TRACE_HIT_CACHE() do { g_totalPageCacheHit++; } while (0)
57 
ResetPageCacheHitInfo(int * try,int * hit)58 VOID ResetPageCacheHitInfo(int *try, int *hit)
59 {
60     *try = g_totalPageCacheTry;
61     *hit = g_totalPageCacheHit;
62     g_totalPageCacheHit = 0;
63     g_totalPageCacheTry = 0;
64 }
65 #else
66 #define TRACE_TRY_CACHE()
67 #define TRACE_HIT_CACHE()
68 #endif
69 
70 #ifdef LOSCFG_KERNEL_VM
71 
OsPageCacheAdd(LosFilePage * page,struct page_mapping * mapping,VM_OFFSET_T pgoff)72 STATIC VOID OsPageCacheAdd(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff)
73 {
74     LosFilePage *fpage = NULL;
75 
76     LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
77         if (fpage->pgoff > pgoff) {
78             LOS_ListTailInsert(&fpage->node, &page->node);
79             goto done_add;
80         }
81     }
82 
83     LOS_ListTailInsert(&mapping->page_list, &page->node);
84 
85 done_add:
86     mapping->nrpages++;
87 }
88 
OsAddToPageacheLru(LosFilePage * page,struct page_mapping * mapping,VM_OFFSET_T pgoff)89 VOID OsAddToPageacheLru(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff)
90 {
91     OsPageCacheAdd(page, mapping, pgoff);
92     OsLruCacheAdd(page, VM_LRU_ACTIVE_FILE);
93 }
94 
OsPageCacheDel(LosFilePage * fpage)95 VOID OsPageCacheDel(LosFilePage *fpage)
96 {
97     /* delete from file cache list */
98     LOS_ListDelete(&fpage->node);
99     fpage->mapping->nrpages--;
100 
101     /* unmap and remove map info */
102     if (OsIsPageMapped(fpage)) {
103         OsUnmapAllLocked(fpage);
104     }
105 
106     LOS_PhysPageFree(fpage->vmPage);
107 
108     LOS_MemFree(m_aucSysMem0, fpage);
109 }
110 
OsAddMapInfo(LosFilePage * page,LosArchMmu * archMmu,VADDR_T vaddr)111 VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr)
112 {
113     LosMapInfo *info = NULL;
114 
115     info = (LosMapInfo *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosMapInfo));
116     if (info == NULL) {
117         VM_ERR("OsAddMapInfo alloc memory failed!");
118         return;
119     }
120     info->page = page;
121     info->archMmu = archMmu;
122     info->vaddr = vaddr;
123 
124     LOS_ListAdd(&page->i_mmap, &info->node);
125     page->n_maps++;
126 }
127 
OsGetMapInfo(const LosFilePage * page,const LosArchMmu * archMmu,VADDR_T vaddr)128 LosMapInfo *OsGetMapInfo(const LosFilePage *page, const LosArchMmu *archMmu, VADDR_T vaddr)
129 {
130     LosMapInfo *info = NULL;
131     const LOS_DL_LIST *immap = &page->i_mmap;
132 
133     LOS_DL_LIST_FOR_EACH_ENTRY(info, immap, LosMapInfo, node) {
134         if ((info->archMmu == archMmu) && (info->vaddr == vaddr) && (info->page == page)) {
135             return info;
136         }
137     }
138 
139     return NULL;
140 }
141 
OsDeletePageCacheLru(LosFilePage * page)142 VOID OsDeletePageCacheLru(LosFilePage *page)
143 {
144     /* delete from lru list */
145     OsLruCacheDel(page);
146     /* delete from cache list and free pmm if needed */
147     OsPageCacheDel(page);
148 }
149 
OsPageCacheUnmap(LosFilePage * fpage,LosArchMmu * archMmu,VADDR_T vaddr)150 STATIC VOID OsPageCacheUnmap(LosFilePage *fpage, LosArchMmu *archMmu, VADDR_T vaddr)
151 {
152     UINT32 intSave;
153     LosMapInfo *info = NULL;
154 
155     LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave);
156     info = OsGetMapInfo(fpage, archMmu, vaddr);
157     if (info == NULL) {
158         VM_ERR("OsPageCacheUnmap get map info failed!");
159     } else {
160         OsUnmapPageLocked(fpage, info);
161     }
162     if (!(OsIsPageMapped(fpage) && ((fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE) ||
163         OsIsPageDirty(fpage->vmPage)))) {
164         OsPageRefDecNoLock(fpage);
165     }
166 
167     LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave);
168 }
169 
OsVmmFileRemove(LosVmMapRegion * region,LosArchMmu * archMmu,VM_OFFSET_T pgoff)170 VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pgoff)
171 {
172     UINT32 intSave;
173     vaddr_t vaddr;
174     paddr_t paddr = 0;
175     struct Vnode *vnode = NULL;
176     struct page_mapping *mapping = NULL;
177     LosFilePage *fpage = NULL;
178     LosFilePage *tmpPage = NULL;
179     LosVmPage *mapPage = NULL;
180 
181     if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL)) {
182         return;
183     }
184     vnode = region->unTypeData.rf.vnode;
185     mapping = &vnode->mapping;
186     vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT);
187 
188     status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL);
189     if (status != LOS_OK) {
190         return;
191     }
192 
193     mapPage = LOS_VmPageGet(paddr);
194 
195     /* is page is in cache list */
196     LOS_SpinLockSave(&mapping->list_lock, &intSave);
197     fpage = OsFindGetEntry(mapping, pgoff);
198     /* no cache or have cache but not map(cow), free it direct */
199     if ((fpage == NULL) || (fpage->vmPage != mapPage)) {
200         LOS_PhysPageFree(mapPage);
201         LOS_ArchMmuUnmap(archMmu, vaddr, 1);
202     /* this is a page cache map! */
203     } else {
204         OsPageCacheUnmap(fpage, archMmu, vaddr);
205         if (OsIsPageDirty(fpage->vmPage)) {
206             tmpPage = OsDumpDirtyPage(fpage);
207         }
208     }
209     LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
210 
211     if (tmpPage) {
212         OsDoFlushDirtyPage(tmpPage);
213     }
214     return;
215 }
216 
OsMarkPageDirty(LosFilePage * fpage,const LosVmMapRegion * region,INT32 off,INT32 len)217 VOID OsMarkPageDirty(LosFilePage *fpage, const LosVmMapRegion *region, INT32 off, INT32 len)
218 {
219     if (region != NULL) {
220         OsSetPageDirty(fpage->vmPage);
221         fpage->dirtyOff = off;
222         fpage->dirtyEnd = len;
223     } else {
224         OsSetPageDirty(fpage->vmPage);
225         if ((off + len) > fpage->dirtyEnd) {
226             fpage->dirtyEnd = off + len;
227         }
228 
229         if (off < fpage->dirtyOff) {
230             fpage->dirtyOff = off;
231         }
232     }
233 }
234 
GetDirtySize(LosFilePage * fpage,struct Vnode * vnode)235 STATIC UINT32 GetDirtySize(LosFilePage *fpage, struct Vnode *vnode)
236 {
237     UINT32 fileSize;
238     UINT32 dirtyBegin;
239     UINT32 dirtyEnd;
240     struct stat buf_stat;
241 
242     if (stat(vnode->filePath, &buf_stat) != OK) {
243         VM_ERR("FlushDirtyPage get file size failed. (filePath=%s)", vnode->filePath);
244         return 0;
245     }
246 
247     fileSize = buf_stat.st_size;
248     dirtyBegin = ((UINT32)fpage->pgoff << PAGE_SHIFT);
249     dirtyEnd = dirtyBegin + PAGE_SIZE;
250 
251     if (dirtyBegin >= fileSize) {
252         return 0;
253     }
254 
255     if (dirtyEnd >= fileSize) {
256         return fileSize - dirtyBegin;
257     }
258 
259     return PAGE_SIZE;
260 }
261 
OsFlushDirtyPage(LosFilePage * fpage)262 STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage)
263 {
264     UINT32 ret;
265     size_t len;
266     char *buff = NULL;
267     struct Vnode *vnode = fpage->mapping->host;
268     if (vnode == NULL) {
269         VM_ERR("page cache vnode error");
270         return LOS_NOK;
271     }
272 
273     len = fpage->dirtyEnd - fpage->dirtyOff;
274     len = (len == 0) ? GetDirtySize(fpage, vnode) : len;
275     if (len == 0) {
276         OsCleanPageDirty(fpage->vmPage);
277         return LOS_OK;
278     }
279 
280     buff = (char *)OsVmPageToVaddr(fpage->vmPage);
281 
282     /* actually, we did not update the fpage->dirtyOff */
283     ret = vnode->vop->WritePage(vnode, (VOID *)buff, fpage->pgoff, len);
284     if (ret <= 0) {
285         VM_ERR("WritePage error ret %d", ret);
286     } else {
287         OsCleanPageDirty(fpage->vmPage);
288     }
289     ret = (ret <= 0) ? LOS_NOK : LOS_OK;
290 
291     return ret;
292 }
293 
OsDumpDirtyPage(LosFilePage * oldFPage)294 LosFilePage *OsDumpDirtyPage(LosFilePage *oldFPage)
295 {
296     LosFilePage *newFPage = NULL;
297 
298     newFPage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage));
299     if (newFPage == NULL) {
300         VM_ERR("Failed to allocate for temp page!");
301         return NULL;
302     }
303 
304     OsCleanPageDirty(oldFPage->vmPage);
305     (VOID)memcpy_s(newFPage, sizeof(LosFilePage), oldFPage, sizeof(LosFilePage));
306 
307     return newFPage;
308 }
309 
OsDoFlushDirtyPage(LosFilePage * fpage)310 VOID OsDoFlushDirtyPage(LosFilePage *fpage)
311 {
312     if (fpage == NULL) {
313         return;
314     }
315     (VOID)OsFlushDirtyPage(fpage);
316     LOS_MemFree(m_aucSysMem0, fpage);
317 }
318 
OsReleaseFpage(struct page_mapping * mapping,LosFilePage * fpage)319 STATIC VOID OsReleaseFpage(struct page_mapping *mapping, LosFilePage *fpage)
320 {
321     UINT32 intSave;
322     UINT32 lruSave;
323     SPIN_LOCK_S *lruLock = &fpage->physSeg->lruLock;
324     LOS_SpinLockSave(&mapping->list_lock, &intSave);
325     LOS_SpinLockSave(lruLock, &lruSave);
326     OsCleanPageLocked(fpage->vmPage);
327     OsDeletePageCacheLru(fpage);
328     LOS_SpinUnlockRestore(lruLock, lruSave);
329     LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
330 }
331 
OsDelMapInfo(LosVmMapRegion * region,LosVmPgFault * vmf,BOOL cleanDirty)332 VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty)
333 {
334     UINT32 intSave;
335     LosMapInfo *info = NULL;
336     LosFilePage *fpage = NULL;
337     struct page_mapping *mapping = NULL;
338 
339     if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) {
340         return;
341     }
342 
343     mapping = &region->unTypeData.rf.vnode->mapping;
344     LOS_SpinLockSave(&mapping->list_lock, &intSave);
345     fpage = OsFindGetEntry(mapping, vmf->pgoff);
346     if (fpage == NULL) {
347         LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
348         return;
349     }
350 
351     if (cleanDirty) {
352         OsCleanPageDirty(fpage->vmPage);
353     }
354     info = OsGetMapInfo(fpage, &region->space->archMmu, (vaddr_t)vmf->vaddr);
355     if (info != NULL) {
356         fpage->n_maps--;
357         LOS_ListDelete(&info->node);
358         LOS_AtomicDec(&fpage->vmPage->refCounts);
359         LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
360         LOS_MemFree(m_aucSysMem0, info);
361         return;
362     }
363     LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
364 }
365 
OsVmmFileFault(LosVmMapRegion * region,LosVmPgFault * vmf)366 INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
367 {
368     INT32 ret;
369     VOID *kvaddr = NULL;
370 
371     UINT32 intSave;
372     bool newCache = false;
373     struct Vnode *vnode = NULL;
374     struct page_mapping *mapping = NULL;
375     LosFilePage *fpage = NULL;
376 
377     if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) {
378         VM_ERR("Input param is NULL");
379         return LOS_NOK;
380     }
381     vnode = region->unTypeData.rf.vnode;
382     mapping = &vnode->mapping;
383 
384     /* get or create a new cache node */
385     LOS_SpinLockSave(&mapping->list_lock, &intSave);
386     fpage = OsFindGetEntry(mapping, vmf->pgoff);
387     TRACE_TRY_CACHE();
388     if (fpage != NULL) {
389         TRACE_HIT_CACHE();
390         OsPageRefIncLocked(fpage);
391     } else {
392         fpage = OsPageCacheAlloc(mapping, vmf->pgoff);
393         if (fpage == NULL) {
394             LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
395             VM_ERR("Failed to alloc a page frame");
396             return LOS_NOK;
397         }
398         newCache = true;
399     }
400     OsSetPageLocked(fpage->vmPage);
401     LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
402     kvaddr = OsVmPageToVaddr(fpage->vmPage);
403 
404     /* read file to new page cache */
405     if (newCache) {
406         ret = vnode->vop->ReadPage(vnode, kvaddr, fpage->pgoff << PAGE_SHIFT);
407         if (ret == 0) {
408             VM_ERR("Failed to read from file!");
409             OsReleaseFpage(mapping, fpage);
410             return LOS_NOK;
411         }
412         LOS_SpinLockSave(&mapping->list_lock, &intSave);
413         OsAddToPageacheLru(fpage, mapping, vmf->pgoff);
414         LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
415     }
416 
417     LOS_SpinLockSave(&mapping->list_lock, &intSave);
418     /* cow fault case no need to save mapinfo */
419     if (!((vmf->flags & VM_MAP_PF_FLAG_WRITE) && !(region->regionFlags & VM_MAP_REGION_FLAG_SHARED))) {
420         OsAddMapInfo(fpage, &region->space->archMmu, (vaddr_t)vmf->vaddr);
421         fpage->flags = region->regionFlags;
422     }
423 
424     /* share page fault, mark the page dirty */
425     if ((vmf->flags & VM_MAP_PF_FLAG_WRITE) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) {
426         OsMarkPageDirty(fpage, region, 0, 0);
427     }
428 
429     vmf->pageKVaddr = kvaddr;
430     LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
431     return LOS_OK;
432 }
433 
OsFileCacheFlush(struct page_mapping * mapping)434 VOID OsFileCacheFlush(struct page_mapping *mapping)
435 {
436     UINT32 intSave;
437     UINT32 lruLock;
438     LOS_DL_LIST_HEAD(dirtyList);
439     LosFilePage *ftemp = NULL;
440     LosFilePage *fpage = NULL;
441 
442     if (mapping == NULL) {
443         return;
444     }
445     LOS_SpinLockSave(&mapping->list_lock, &intSave);
446     LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
447         LOS_SpinLockSave(&fpage->physSeg->lruLock, &lruLock);
448         if (OsIsPageDirty(fpage->vmPage)) {
449             ftemp = OsDumpDirtyPage(fpage);
450             if (ftemp != NULL) {
451                 LOS_ListTailInsert(&dirtyList, &ftemp->node);
452             }
453         }
454         LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, lruLock);
455     }
456     LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
457 
458     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, ftemp, &dirtyList, LosFilePage, node) {
459         OsDoFlushDirtyPage(fpage);
460     }
461 }
462 
OsFileCacheRemove(struct page_mapping * mapping)463 VOID OsFileCacheRemove(struct page_mapping *mapping)
464 {
465     UINT32 intSave;
466     UINT32 lruSave;
467     SPIN_LOCK_S *lruLock = NULL;
468     LOS_DL_LIST_HEAD(dirtyList);
469     LosFilePage *ftemp = NULL;
470     LosFilePage *fpage = NULL;
471     LosFilePage *fnext = NULL;
472 
473     LOS_SpinLockSave(&mapping->list_lock, &intSave);
474     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &mapping->page_list, LosFilePage, node) {
475         lruLock = &fpage->physSeg->lruLock;
476         LOS_SpinLockSave(lruLock, &lruSave);
477         if (OsIsPageDirty(fpage->vmPage)) {
478             ftemp = OsDumpDirtyPage(fpage);
479             if (ftemp != NULL) {
480                 LOS_ListTailInsert(&dirtyList, &ftemp->node);
481             }
482         }
483 
484         OsDeletePageCacheLru(fpage);
485         LOS_SpinUnlockRestore(lruLock, lruSave);
486     }
487     LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
488 
489     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) {
490         OsDoFlushDirtyPage(fpage);
491     }
492 }
493 
494 LosVmFileOps g_commVmOps = {
495     .open = NULL,
496     .close = NULL,
497     .fault = OsVmmFileFault,
498     .remove = OsVmmFileRemove,
499 };
500 
OsVfsFileMmap(struct file * filep,LosVmMapRegion * region)501 INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
502 {
503     region->unTypeData.rf.vmFOps = &g_commVmOps;
504     region->unTypeData.rf.vnode = filep->f_vnode;
505     region->unTypeData.rf.f_oflags = filep->f_oflags;
506 
507     return ENOERR;
508 }
509 
OsNamedMMap(struct file * filep,LosVmMapRegion * region)510 STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
511 {
512     struct Vnode *vnode = NULL;
513     if (filep == NULL) {
514         return LOS_ERRNO_VM_MAP_FAILED;
515     }
516     file_hold(filep);
517     vnode = filep->f_vnode;
518     VnodeHold();
519     vnode->useCount++;
520     VnodeDrop();
521     if (filep->ops != NULL && filep->ops->mmap != NULL) {
522         if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) {
523             LOS_SetRegionTypeDev(region);
524         } else {
525             LOS_SetRegionTypeFile(region);
526         }
527         int ret = filep->ops->mmap(filep, region);
528         if (ret != LOS_OK) {
529             file_release(filep);
530             return LOS_ERRNO_VM_MAP_FAILED;
531         }
532     } else {
533         VM_ERR("mmap file type unknown");
534         file_release(filep);
535         return LOS_ERRNO_VM_MAP_FAILED;
536     }
537     file_release(filep);
538     return LOS_OK;
539 }
540 
OsFindGetEntry(struct page_mapping * mapping,VM_OFFSET_T pgoff)541 LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
542 {
543     LosFilePage *fpage = NULL;
544 
545     LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
546         if (fpage->pgoff == pgoff) {
547             return fpage;
548         }
549 
550         if (fpage->pgoff > pgoff) {
551             break;
552         }
553     }
554 
555     return NULL;
556 }
557 
558 /* need mutex & change memory to dma zone. */
OsPageCacheAlloc(struct page_mapping * mapping,VM_OFFSET_T pgoff)559 LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff)
560 {
561     VOID *kvaddr = NULL;
562     LosVmPhysSeg *physSeg = NULL;
563     LosVmPage *vmPage = NULL;
564     LosFilePage *fpage = NULL;
565 
566     vmPage = LOS_PhysPageAlloc();
567     if (vmPage == NULL) {
568         VM_ERR("alloc vm page failed");
569         return NULL;
570     }
571     physSeg = OsVmPhysSegGet(vmPage);
572     kvaddr = OsVmPageToVaddr(vmPage);
573     if ((physSeg == NULL) || (kvaddr == NULL)) {
574         LOS_PhysPageFree(vmPage);
575         VM_ERR("alloc vm page failed!");
576         return NULL;
577     }
578 
579     fpage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage));
580     if (fpage == NULL) {
581         LOS_PhysPageFree(vmPage);
582         VM_ERR("Failed to allocate for page!");
583         return NULL;
584     }
585 
586     (VOID)memset_s((VOID *)fpage, sizeof(LosFilePage), 0, sizeof(LosFilePage));
587 
588     LOS_ListInit(&fpage->i_mmap);
589     LOS_ListInit(&fpage->node);
590     LOS_ListInit(&fpage->lru);
591     fpage->n_maps = 0;
592     fpage->dirtyOff = PAGE_SIZE;
593     fpage->dirtyEnd = 0;
594     fpage->physSeg = physSeg;
595     fpage->vmPage = vmPage;
596     fpage->mapping = mapping;
597     fpage->pgoff = pgoff;
598     (VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE);
599 
600     return fpage;
601 }
602 
603 #ifndef LOSCFG_FS_VFS
OsVfsFileMmap(struct file * filep,LosVmMapRegion * region)604 INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
605 {
606     UNUSED(filep);
607     UNUSED(region);
608     return ENOERR;
609 }
610 #endif
611 
612 #endif
613