免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: chishanmingshen
打印 上一主题 下一主题

[内存管理] handle_pte_fault的一个疑问 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2013-01-28 17:13 |只看该作者
1. pte_same()这个函数比较的是整个32bit, 低12bit也参与比较? tlb也能感知低12bit?
low 12bits裝的是pte的attribute,所以當然要比較,這邊可以參考cpu的spec,arm or ia32都寫得很詳細。

2. 何时same? 感觉都是不相同的场景啊!

int handle_pte_fault(struct mm_struct *mm,
                     struct vm_area_struct *vma, unsigned long address,
                     pte_t *pte, pmd_t *pmd, unsigned int flags)
{
        pte_t entry;
        spinlock_t *ptl;

        entry = *pte;
        if (!pte_present(entry)) {
                if (pte_none(entry)) {
                        if (vma->vm_ops) {
                                if (likely(vma->vm_ops->fault))
                                        return do_linear_fault(mm, vma, address,
                                                pte, pmd, flags, entry);
                        }   
                        return do_anonymous_page(mm, vma, address,
                                                 pte, pmd, flags);
                }   
                if (pte_file(entry))
                        return do_nonlinear_fault(mm, vma, address,
                                        pte, pmd, flags, entry);
                return do_swap_page(mm, vma, address,
                                        pte, pmd, flags, entry);
        }   

        ptl = pte_lockptr(mm, pmd);
        spin_lock(ptl);
        /* 這裡的same應該判斷是否上面四種其中一種已經做過,如果做過就一定不等於
          * 則就不用再往下處理copy-on-write的情況,直接跳到function的尾巴unlock
         */

        if (unlikely(!pte_same(*pte, entry)))
                goto unlock;
        if (flags & FAULT_FLAG_WRITE) {
                if (!pte_write(entry))
                        return do_wp_page(mm, vma, address,
                                        pte, pmd, ptl, entry);
                entry = pte_mkdirty(entry);
        }   
        entry = pte_mkyoung(entry);
        /* ptep_set_access_flags裡面的same我個人是覺得只是要做防呆而以。*/
        if (ptep_set_access_flags(vma, address, pte, entry, flags & FAULT_FLAG_WRITE)) {
                update_mmu_cache(vma, address, pte);
        } else {
                /*   
                 * This is needed only for protection faults but the arch code
                 * is not yet telling us if this is a protection fault or not.
                 * This still avoids useless tlb flushes for .text page faults
                 */
                if (flags & FAULT_FLAG_WRITE)
                        flush_tlb_fix_spurious_fault(vma, address);
        }
unlock:
        pte_unmap_unlock(pte, ptl);
        return 0;
}
                                                                                

3. 照你说的, fault的处理是改pte并设置tlb无效, 那么tlb miss的处理是cpu自动完成的?
tlb miss在x86裡面是硬體完成,arm裡面有hardware page table walker,預設也是硬體完成。

4. 你提到"包括linear fault, anonymous fault, non-linear fault, swap fault, copy-on-write這些對

page table的更改", 这些fault有何同性? 不是所有的fault都这样么?

linear fault: 是有mmap到檔案的fault,這時候要去page cache所在的radix tree撈(minor fault),

撈不到則到block system上撈(major fault)。

anonymous fault: 沒有map到file,直接從buddy system要一個page,初始化為零,malloc會用到。

non-linear fault: remap-file-pages會用到,把vma area裡面的一段改map到其他的file。

swap fault: 當要存取的page被放在swap space的時候,這邊會跑去swap space裡面撈。

copy-on-write: 這個os的書裡面有,翻翻silberschat的恐龍本吧。


5. 能举个具体的例子么? 比如写一个page, 此page也具有可写属性, 此时进入这个场景?

可寫屬性除了copy-on-write以外都有可能會進入。因為copy-on-write的時候會改成read-only。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
12 [报告]
发表于 2013-01-28 18:03 |只看该作者
1.  ok


2. 貌似跟你理解的不一样...
/*
* These routines also need to handle stuff like marking pages dirty
* and/or accessed for architectures that don't do it in hardware (most
* RISC architectures).  The early dirtying is also good on the i386.
*
* There is also a hook called "update_mmu_cache()" that architectures
* with external mmu caches can use to update those (ie the Sparc or
* PowerPC hashed page tables that act as extended TLBs).
*
* We enter with non-exclusive mmap_sem (to exclude vma changes,
* but allow concurrent faults), and pte mapped but not yet locked.
* We return with mmap_sem still held, but pte unmapped and unlocked.
*/
int handle_pte_fault(struct mm_struct *mm,
                     struct vm_area_struct *vma, unsigned long address,
                     pte_t *pte, pmd_t *pmd, unsigned int flags)
{
        pte_t entry;
        spinlock_t *ptl;

        entry = *pte;
        if (!pte_present(entry)) {
                if (pte_none(entry)) {
                        if (vma->vm_ops) {
                                if (likely(vma->vm_ops->fault))
                                        return do_linear_fault(mm, vma, address,
                                                pte, pmd, flags, entry);
                        }
                        return do_anonymous_page(mm, vma, address,
                                                 pte, pmd, flags);
                }
                if (pte_file(entry))
                        return do_nonlinear_fault(mm, vma, address,
                                        pte, pmd, flags, entry);
                return do_swap_page(mm, vma, address,
                                        pte, pmd, flags, entry);
        }

        ptl = pte_lockptr(mm, pmd);
        spin_lock(ptl);
        if (unlikely(!pte_same(*pte, entry)))<--到这里应该一直same啊!没有不same的时候...?
                goto unlock;
        if (flags & FAULT_FLAG_WRITE) {
                if (!pte_write(entry))
                        return do_wp_page(mm, vma, address,
                                        pte, pmd, ptl, entry);
                entry = pte_mkdirty(entry);<------此处会改entry,所以下面的ptep_set_access_flags()会有不same的时候
        }
        entry = pte_mkyoung(entry);<----此处会改entry,所以下面的ptep_set_access_flags()会有不same的时候
        if (ptep_set_access_flags(vma, address, pte, entry, flags & FAULT_FLAG_WRITE)) {
                update_mmu_cache(vma, address, pte);
        } else {
                /*
                 * This is needed only for protection faults but the arch code
                 * is not yet telling us if this is a protection fault or not.
                 * This still avoids useless tlb flushes for .text page faults
                 * with threads.
                 */
                if (flags & FAULT_FLAG_WRITE)
                        flush_tlb_fix_spurious_fault(vma, address);
        }
unlock:
        pte_unmap_unlock(pte, ptl);
        return 0;
}


3. ok

4/5. 我再想想......


再次感谢!!!

回复 10# bboytaiwan


   

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
13 [报告]
发表于 2013-01-28 18:14 |只看该作者
本帖最后由 chishanmingshen 于 2013-01-28 18:15 编辑


其实 我就是想知道何时能走到这种case?

因为象swap/cow等pte fault都有独立的处理了.

论坛徽章:
0
14 [报告]
发表于 2013-01-28 18:36 |只看该作者
不好意思,剛剛在上班回太快了,沒看清楚,下面這個是thread & process的re-entry問題,晚點再來回。

if (unlikely(!pte_same(*pte, entry)))<--到这里应该一直same啊!没有不same的时候...?
                goto unlock;

论坛徽章:
0
15 [报告]
发表于 2013-01-28 22:26 |只看该作者
后面那串应该就是更新TLB,具体怎么回事,和具体体系结构有关。handle_pte_fault应该就是tlb_miss处理最后的一种情况

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
16 [报告]
发表于 2013-01-28 23:31 |只看该作者
MIPS需要os来处理TLB miss的异常
ARM应该不需要吧
x86不了解

论坛徽章:
0
17 [报告]
发表于 2013-01-29 14:36 |只看该作者
本帖最后由 janetliu9 于 2013-01-29 14:37 编辑

我表述不准确。应该是do_page_fault处理的最后可能回到handle_pte_fault, do_page_fault 怎么用的和体系结构有关。mips应该是通用exception入口的1、2、3号exception会到do_page_fault, 还有一个专用tlb miss,不会到do_page_fault.    没做过x86, 扫了一眼好像14号trap是page_fault,具体怎么回事不知。除了do_page_fault还有mmap 之类的也可能会到handle_pte_fault.

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
18 [报告]
发表于 2013-01-30 13:07 |只看该作者
不明白...啊...

论坛徽章:
0
19 [报告]
发表于 2013-02-03 18:38 |只看该作者
bboytaiwan 发表于 2013-01-28 18:36
不好意思,剛剛在上班回太快了,沒看清楚,下面這個是thread & process的re-entry問題,晚點再來回。

i ...


恩。什么情况下entry和pte.value不同?

期待答案。

论坛徽章:
0
20 [报告]
发表于 2013-02-03 18:47 |只看该作者
chishanmingshen 发表于 2013-01-21 15:30
from 2.6.11

        if (write_access) {
                if (!pte_write(entry))
                        return do_wp_page(mm, vma, address, pte, pmd, entry);

                entry = pte_mkdirty(entry);
        }


       <---------------------------------------------------------下面这个分支是哪种场景???谢谢!!!
        entry = pte_mkyoung(entry);
        ptep_set_access_flags(vma, address, pte, entry, write_access);
        update_mmu_cache(vma, address, entry);
        pte_unmap(pte);
        spin_unlock(&mm->page_table_lock);
        return VM_FAULT_MINOR;
}


当“pte_present()==true” 的时候, 执行到这里,只能是处理cow的页吗?那么就只能走do_wp_page了。
还有其他非cow的情况吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP