2.9 linux存储管理-页面的换入
来源:互联网 发布:fft算法 c语言 编辑:程序博客网 时间:2024/05/24 15:40
线性地址-->物理地址
若映射已经建立,但相应页表|页目录的P(present)位为0,表示相应的物理页面不再内存,从而无法访问内存。对于这种情况和未建立映射的情况,CPU的MMU硬件不对其进行区分,都进行“页面异常”处理
在handle_page_fault函数中:
说明:
首先区分的是pte_present,也就是检查表项的P标志位,查看物理页面是否在内存中。
若不在内存中,则通过pte_none检测表项是否为空(all 0),
若为空,则说明页面的映射尚未建立,调用do_no_page
如果非空,则说明映射已经建立,只是物理页面不再内存中,调用do_swap_page,将该页面换入内存
代码:
static inline int handle_pte_fault(struct mm_struct *mm,
struct vm_area_struct * vma, unsigned long address,
int write_access, pte_t * pte)
{
pte_t entry;
/*
* We need the page table lock to synchronize with kswapd
* and the SMP-safe atomic PTE updates.
*/
spin_lock(&mm->page_table_lock);
entry = *pte;
if (!pte_present(entry)) {
/*
* If it truly wasn't present, we know that kswapd
* and the PTE updates will not touch it later. So
* drop the lock.
*/
spin_unlock(&mm->page_table_lock);
if (pte_none(entry))
return do_no_page(mm, vma, address, write_access, pte);
return do_swap_page(mm, vma, address, pte, pte_to_swp_entry(entry), write_access);
}
do_swap_page函数代码:
说明:
address为映射失败的线性地址
page_table为映射失败的页面表项,entry为表项内容
( 当页面在物理内存中时,页面表项为pte_t结构
当page不再物理内存时,页面表项为swap_entry_t结构)
write_access表示映射失败时所进行的访问种类(read/write)
lookup_swap_cache:先检查页面是否在换进/换出队列中(尚未换出到磁盘)
swapin_readahead:从磁盘上预读多个页面到 换进/换出队列 和 活跃页面队列(效率问题)
预读可能由于无法分配到足够页面而失败(重读,并只读entry页面)
read_swap_cache:从活跃页面队列读取entry
代码:
static int do_swap_page(struct mm_struct * mm,
struct vm_area_struct * vma, unsigned long address,
pte_t * page_table, swp_entry_t entry, int write_access)
{
struct page *page = lookup_swap_cache(entry);
pte_t pte;
if (!page) {
lock_kernel();
swapin_readahead(entry);
page = read_swap_cache(entry);
unlock_kernel();
if (!page)
return -1;
flush_page_to_ram(page);
flush_icache_page(vma, page);
}
mm->rss++;
pte = mk_pte(page, vma->vm_page_prot);
/*
* Freeze the "shared"ness of the page, ie page_count + swap_count.
* Must lock page before transferring our swap count to already
* obtained page count.
*/
lock_page(page);
swap_free(entry);
if (write_access && !is_page_shared(page))
pte = pte_mkwrite(pte_mkdirty(pte));
UnlockPage(page);
set_pte(page_table, pte);
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, address, pte);
return 1; /* Minor fault */
- }
read_swap_cache函数:
说明:
read_swap_cache函数只是调用了read_swap_cache_async(),并把参数wait设置为1
lookup_swap_cache执行了两次
第一次:因为swapin_readahead已经把目标读取进来,需要在swaper_space队列中寻找一次
第二次:lookup_swap_cache并未找到页面,使用__get_free_page申请页面,
但是申请过程中可能会被阻塞(可能有其他进程将entry换入内存),需要再次
在swaper_space和avtive_list中查找一次,若找到说明被其他进程换入,
跳转到out_free_page,释放__get_free_page申请的页面,
并使用swap_free减少entry的共享计数(swap_duplicate(entry)增加了共享计数)
代码:
struct page * read_swap_cache_async(swp_entry_t entry, int wait)
{
struct page *found_page = 0, *new_page;
unsigned long new_page_addr;
/*
*Make sure the swap entry is still in use.
*/
if(!swap_duplicate(entry)) /* Account for the swap cache */
goto out;
/*
*Look for the page in the swap cache.
*/
found_page = lookup_swap_cache(entry);
if (found_page)
goto out_free_swap;
new_page_addr = __get_free_page(GFP_USER);
if (!new_page_addr)
goto out_free_swap;
/*Out of memory */
new_page= virt_to_page(new_page_addr);
/*
*Check the swap cache again, in case we stalled above.
*/
found_page = lookup_swap_cache(entry);
if(found_page)
goto out_free_page;
/*
*Add it to the swap cache and read its contents.
*/
lock_page(new_page);
add_to_swap_cache(new_page, entry);
rw_swap_page(READ, new_page, wait);
return new_page;
- out_free_page:
page_cache_release(new_page);
out_free_swap:
swap_free(entry);
out:
return found_page;
}
阅读全文
0 0
- 2.9 linux存储管理-页面的换入
- 【存储管理】页面的换入
- Linux 存储管理 缺页中断和页面换入
- 页面的换入
- Linux内核源代码情景分析-内存管理之用户页面的换入
- Linux内核页面换入换出
- 4、操作系统内存管理——页面的换入换出
- linux内核源代码学习(5)内存页面的换入换出
- 关于程序导致的页面换入换出
- 2.6 Linux存储管理-物理页面的使用和周转
- 2.7 Linux存储管理-物理页面分配
- 存储管理的页面置换算法
- 存储管理的页面置换算法
- 存储管理的页面置换算法
- 存储管理的页面置换算法
- 存储管理的页面置换算法
- 【存储管理】物理页面的分配
- 【存储管理】页面的定期换出page_launder()
- CBB电容代替电容的情况及两者区别
- sql server 2005 ssms 竟然没装上
- SDNU 51nod 几道简单的博弈题目
- 2011-2014,构建原子力显微镜的感悟
- Java泛型编程与多态、重载的同与不同
- 2.9 linux存储管理-页面的换入
- DX9鼠标拾取网格轨迹
- Java用socket实现简单的一对一通信
- 浅谈可重入函数与不可重入函数
- 一个高效、稳定、强大的Android刷新库
- 记一次阿里面试
- 关于选择脚本的问题
- 生成函数 应用
- Java Colections 集合类 —— List、ArrayList、Set(HashSet)