Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1262977
  • 博文数量: 185
  • 博客积分: 495
  • 博客等级: 下士
  • 技术积分: 1418
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-02 15:12
个人简介

治肾虚不含糖,专注内核性能优化二十年。 https://github.com/KnightKu

文章分类

全部博文(185)

文章存档

2019年(1)

2018年(12)

2017年(5)

2016年(23)

2015年(1)

2014年(22)

2013年(82)

2012年(39)

分类: LINUX

2015-12-22 15:29:25

我们通常所说的page mapped是指page建立了对应的页表项,但是其实还有一种mapped是指page被映射到用户态线性地址,及我们通常所说的建立vma,这两种mapped很容易混淆,咱这来一次性把这个给理清楚。

点击(此处)折叠或打开

  1. /*
  2.  * Might pages of this file be mapped into userspace?
  3.  */
  4. static inline int mapping_mapped(struct address_space *mapping)
  5. {
  6.     return    !RB_EMPTY_ROOT(&mapping->i_mmap);
  7. }

点击(此处)折叠或打开

  1. /*
  2.  * Return true if this page is mapped into pagetables.
  3.  */
  4. static inline int page_mapped(struct page *page)
  5. {
  6.     return atomic_read(&(page)->_mapcount) >= 0;
  7. }
偶然碰到个社区有人发用page_mapped替代mapping_mapped来检测page是否真正被*mapped*的patch,于是扒了下kernel的代码和changelog,发现Lei Ming以前发的提升arm flush dcache的patch:
commit 81f28946a8b066d484ca8935ff545d94ce730aa3
Author: Ming Lei
Date:   Wed Jun 5 02:44:00 2013 +0100

    ARM: 7746/1: mm: lazy cache flushing on non-mapped pages
    
    Currently flush_dcache_page() thinks pages as non-mapped if
    mapping_mapped(mapping) return false. This approach is very
    coase:
        - mmap on part of file may cause all pages backed on
        the file being thought as mmaped
    
        - file-backed pages aren't mapped into user space actually
        if the memory mmaped on the file isn't accessed
    
    This patch uses page_mapped() to decide if the page has been
    mapped.

comment里面写得很详细了,检测page是否被mapped最好是从page本身出发,而不应该通过上层的address_space,我们知道一个文件只会用一个address_space来管理所有属于它的page,这就可能出现comment说的这种情况,file先被mmap了一段,后续被load进来的page的mapping还是指向这个address_space,页表已经建好,但是如果没有被用户态线程访问,那就不会分配对应的vma (rb-tree节点),好,那现在如果把前面的mmap解除,address_space的rb-tree会被清空,这个时候如果再通过mapping_mapped检测后面load进来的page是否mapped,则会返回false,但是实际上不是,这样在truncate或者invalidate page的时候出现遗漏。
再来看page_mapped,它是直接检测_mapcount,这个参数初始化是-1,在buddy里面的时候也是负值,一旦建立页表(mapped)的就没被设置为非负值,所有通过它来检测一个page是否建立页表才是最严谨的,或者说唯一正确的方式。
阅读(2601) | 评论(0) | 转发(0) |
0

上一篇:linux percpu机制解析

下一篇:抢占式内核

给主人留下些什么吧!~~