博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[内核内存] [arm64] 内存回收5---add_to_swap函数详解
阅读量:4281 次
发布时间:2019-05-27

本文共 2863 字,大约阅读时间需要 9 分钟。

add_to_swap函数是为匿名页面分配交换空间.

当对一个匿名页面page进行内存回收时,若该匿名页面page具有如下状态

1.该匿名页未被用户应用访问.(映射该匿名页的所有pte页表项的AF位为0)2.PageAnon(page) && !PageSwapCache(page)为true.(该page未被分配swap空间)

若此时页面回收则允许页面进行文件操作或磁盘I/0操作(sc->gfp_mask & __GFP_IO为true).则页面回收则会调用add_to_swap函数对page分配swap交换空间

  1. 执行步骤

    1.通过get_swap_page在swap area中获取一个slot(页槽,一个页槽用于存储一个匿名页swap out到swap area中的内   容数据),并将该slot的位置信	  息记录在swp_entry_t结构体entry中2.通过add_to_swap_cache函数将1步骤分配的slot与匿名页page关联	a.将匿名页page的flag成员的swap cache标志位置位	b.用匿名页page的private成员记录步骤1获取的slot在swap area中的位置信息(page->private = entry.val)	c.通过swp_offset(entry)函数获取步骤1的slot在swap area中的偏移offset	d.通过radix_tree_insert函数将匿名页page插入到对应swap area区域缓存管理器address_space的page_tree		  容器中.
  2. 源码

    //mm/swap_state.c/** * add_to_swap - allocate swap space for a page * @page: page we want to move to swap * * Allocate swap space for the page and add the page to the * swap cache.  Caller needs to hold the page lock.  */int add_to_swap(struct page *page, struct list_head *list){
    swp_entry_t entry; int err; VM_BUG_ON_PAGE(!PageLocked(page), page); VM_BUG_ON_PAGE(!PageUptodate(page), page); /* *从swap磁盘区域获取一个slot(slot代表一个槽,每个槽对应内存区域的一个page),并将该槽的位置信息记录 *在swp_entry_t结构体entry中(通过entry可以在从一个swap磁盘区域定位到一个具体的slot,该slot用于存储 *匿名页page对应的数据). */ entry = get_swap_page(); ...... err = add_to_swap_cache(page, entry, __GFP_HIGH|__GFP_NOMEMALLOC|__GFP_NOWARN); ...... //成功返回1,失败返回0}
    //mm/swap_state.c/* *int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) *					|--->__add_to_swap_cache(page, entry) *//* * __add_to_swap_cache resembles add_to_page_cache_locked on swapper_space, * but sets SwapCache flag and private instead of mapping and index. */int __add_to_swap_cache(struct page *page, swp_entry_t entry){
    int error; //某个swap 内存区域的swap cache管理结构体struct address_space struct address_space *address_space; ..... get_page(page); //将匿名页page的flag成员的swap cache标志位置位 SetPageSwapCache(page); //匿名页page的private存储page对应的swap slot的位置信息 set_page_private(page, entry.val); //获取entry所在swap area区域的swap cache管理器,赋值给address_space address_space = swap_address_space(entry); //获取address_space缓存管理器中page_tree的自旋锁 spin_lock_irq(&address_space->tree_lock); //根据entry指向的slot在对应swap area的偏移,将page插入到缓存管理器的page_tree中 error = radix_tree_insert(&address_space->page_tree, swp_offset(entry), page); if (likely(!error)) {
    //page插入成功,缓存管理器address_sapce维护的swap cache中匿名缓存页数量++ address_space->nrpages++; __inc_node_page_state(page, NR_FILE_PAGES); INC_CACHE_INFO(add_total); } spin_unlock_irq(&address_space->tree_lock); if (unlikely(error)) {
    /* * Only the context which have set SWAP_HAS_CACHE flag * would call add_to_swap_cache(). * So add_to_swap_cache() doesn't returns -EEXIST. */ VM_BUG_ON(error == -EEXIST); set_page_private(page, 0UL); ClearPageSwapCache(page); put_page(page); } return error;}

转载地址:http://wpbgi.baihongyu.com/

你可能感兴趣的文章
spring与mybatis项目出现 java.lang.NumberFormatException: For input string: "${jdbc.ma
查看>>
Nginx学习笔记
查看>>
使用Squid搭建局域网视频缓存代理
查看>>
POI读取word2003和word2007
查看>>
使用Squid搭建内网视频缓存系统
查看>>
Tomcat 开启GZIP压缩网页
查看>>
malloc 详解
查看>>
如何在自定义Listener(监听器)中使用Spring容器管理的bean
查看>>
运维DBA规范(4大纪律9项注意)
查看>>
程序员简历修养
查看>>
ThreadPoolExecutor 判断多线程执行完成
查看>>
神经网络通俗指南:一文看懂神经网络工作原理
查看>>
Windows共享权限和相关管理
查看>>
页面制作HTML+CSS基础乱炖
查看>>
验证最小化可行产品(MVP)的15种方法
查看>>
JVM实用参数系列
查看>>
系统运维(灰度发布)
查看>>
几款强大的PPT制作辅助软件
查看>>
程序员应该常问常思考
查看>>
谈谈高并发系统的限流
查看>>