免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2213 | 回复: 7
打印 上一主题 下一主题

[内存管理] 难道是page cache bug [复制链接]

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-25 10:30 |只看该作者 |倒序浏览
本帖最后由 embeddedlwp 于 2012-04-28 15:37 编辑

在linux 2.6.11中,从page cache删除一个页会调用remove_from_page_cache函数:
  1. 107/*
  2. 108 * Remove a page from the page cache and free it. Caller has to make
  3. 109 * sure the page is locked and that nobody else uses it - or that usage
  4. 110 * is safe.  The caller must hold a write_lock on the mapping's tree_lock.
  5. 111 */
  6. 112void __remove_from_page_cache(struct page *page)
  7. 113{
  8. 114        struct address_space *mapping = page->mapping;
  9. 115
  10. 116        radix_tree_delete(&mapping->page_tree, page->index);
  11. 117        page->mapping = NULL;
  12. 118        mapping->nrpages--;
  13. 119        pagecache_acct(-1);
  14. 120}
  15. 121
  16. 122void remove_from_page_cache(struct page *page)
  17. 123{
  18. 124        struct address_space *mapping = page->mapping;
  19. 125
  20. 126        if (unlikely(!PageLocked(page)))
  21. 127                PAGE_BUG(page);
  22. 128
  23. 129        spin_lock_irq(&mapping->tree_lock);
  24. 130        __remove_from_page_cache(page);
  25. 131        spin_unlock_irq(&mapping->tree_lock);
  26. 132}
复制代码
我也dig了一下radix_tree_delete的实现,但是这个要删除的page只是从page cache中删除了,但是并没有从调用free_page之类的函数释放这个page。

论坛徽章:
0
2 [报告]
发表于 2012-04-25 23:45 |只看该作者
最近刚好遇到一个和这个有关的问题,我稍微说一下我的理解,欢迎讨论

感觉上,page cache 只是一种对内存中存在的页面的一种记录和索引,对page本身没有任何拥有权,
它的目的直观上只是用来加速对该页面的第二次或第二次以上的访问。

从这个意义上来说的话,remove_from_page_cache的目的应该是于page cache的目的相反,
也就是使对该页面的第二次或第二次以上的访问无法得到加速,因为page cache的查找是通过radix tree来进行的,
radix_tree_delete已经完成了remove_from_page_cache的目的,也就是从page cache tree中移除掉记录了这个page的节点,而不是移除掉page本身

从感觉上,操作应该是对称的,也就是因为mmap操作分配到的页面,应该是在unmmap中进行free_page操作。

mapping的时候
alloc page的操作并不是在page cache 的radix tree的node 被分配的时候进行的,而是alloc 了page 之后,再加入到page cache的radix tree中,
这样的话 对应的
unmmaping的时候,free page的操作当然不会在page cache的radix tree node被删除的时候执行,而是在remove_from_page_cache之后,有独立的free_page操作。

而且,更实际的来说,存在 我不想我的page出现在page cache中,但是正常flow会被加入到page cache radix tree中,这样我只好在mapping完成后再手工从page cache radix tree中移除掉这个page的情况也是很常见的。

汗,自己都感觉说的有点乱,不知道能够给您一点启发。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
3 [报告]
发表于 2012-04-26 08:25 |只看该作者
回复 2# onlyxuyang


radix tree在lib下面,是通用库,不应该知道page这个东西,这点我赞成。我比较在意的是注释里提到and free it。

free一个page的场景我已经完全没概念了,但应该涉及一点引用计数的操作,或者走到这里来的时候已经是引用计算归零了。populate page cache也不必到mmap时,普通读写时就可能发生。unmap也未必会从page cache中删东西。从page cache里删东西的情况,我只能想到释放inode的时候和系统内存紧张进行page reclaim的时候。

Linux的缓存系统太复杂了,没人用的dentry会缓存,结果是inode跟着被缓存,最后再扯上page cache和buffer header。涉及的元素东西太多,恐怕得专门留心去总结一下。

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
4 [报告]
发表于 2012-04-26 09:16 |只看该作者
回复 3# tempname2

在linux 3.3.3的代码中这个remove_from_page_cache貌似换了名字,叫delete_from_page_cache:
  1. 158void delete_from_page_cache(struct page *page)
  2. 159{
  3. 160        struct address_space *mapping = page->mapping;
  4. 161        void (*freepage)(struct page *);
  5. 162
  6. 163        BUG_ON(!PageLocked(page));
  7. 164
  8. 165        freepage = mapping->a_ops->freepage;
  9. 166        spin_lock_irq(&mapping->tree_lock);
  10. 167        __delete_from_page_cache(page);
  11. 168        spin_unlock_irq(&mapping->tree_lock);
  12. 169        mem_cgroup_uncharge_cache_page(page);
  13. 170
  14. 171        if (freepage)
  15. 172                freepage(page);
  16. 173        page_cache_release(page);
  17. 174}
复制代码
可以看到这里显示的调用了freepage函数。

论坛徽章:
0
5 [报告]
发表于 2012-04-26 11:01 |只看该作者
本帖最后由 blake326 于 2012-04-26 11:13 编辑

回复 1# embeddedlwp


        说一下我的理解把。

    首先:每个管理区都知道自己有哪几种页框,都在哪里,怎么管理。具体来说有:伙伴系统的free_area,每cpu页框高速缓存per_cpu_pageset,还有几个lru链表分别存放了inactive、active的匿名页框和文件映射页框以及一个不可以回收的lru链表。
ps:我觉得保留页框其实也是free_area的一部分,只有在特殊的情况下,才能使用到。
   
    内存管理就是管理页框在这些区域中流动。分配页框直接从free_area或者per_cpu_pageset获取,一般用户态进程获取到的页框都会加入到lru链表,当free_area不足时,就要从lru释放页框回来,具体的就是转移一部分active的lru页框到inactive页框,释放一部分inactive的lru页框直接到per_cpu_pageset。per_cpu_pageset在适当的时机释放给free_area。

   内存不足时:
do_try_to_free_pages
->shrink_zones
->shrink_zone
->对for_each_evictable_lru执行shrink_list
->对于active的lru执行shrink_active_list,对于inactive的lru执行shrink_inactive_list
->shrink_inactive_list
   isolate_pages_global取出一定数量的可以释放的页框调用shrink_page_list来释放他们.
->shrink_page_list
   对每个page分别进行释放:
   如果正在写回,则等待它写回完成。
   如果页框是referenced的则不能释放,SetPageActive从而回到上面的shrink_inactive_list会将该页框添加到active lru(inactive lru里面的page本身都是referenced清除的,但是如果又被访问的话则重新设置),则继续下一个page。
   如果页框有一个或者多个页表项映射它_mapcount>=0,通过反向映射解除关系。
   如果page是dirty的,写出去。
   如果page是块缓冲的,释放相关buffer_head。
   如果page映射到文件,解除该page和rbtree cache的关系。(你讲得地方,该页已经要呗释放了,不能再通过rbtree cache找到它来访问了)
   
   所有可以被释放的page将会通过free_page_list来释放到per_cpu_pageset,从而释放到free_area。
   
   

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
6 [报告]
发表于 2012-04-27 21:33 |只看该作者
回复 3# tempname2


kernel中怎么没找到对page cache的大小加一个上限,不需要上限吗?


   

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
7 [报告]
发表于 2012-04-27 22:00 |只看该作者
对于没有脏的页,内存不够时直接丢掉就好了。对于脏页,是有比例控制的,一旦超过用户预设的值,就会开始进行回写并释不用的page,直到脏页比例或数量恢复至阈值以下。page cache可能会受此限制,其它因素不太清楚。

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
8 [报告]
发表于 2012-05-29 18:02 |只看该作者
回复 5# blake326

你的意思是说会在内存不足的时候由try_to_free_pages释放,而不是像4楼那样显示的调用free_pages?


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP