免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
21 [报告]
发表于 2013-02-03 19:03 |只看该作者
回复 1# chishanmingshen


    看了一下ulk3.
The handle_pte_fault( ) function is architecture-independent: it considers each possible violation
of the page access rights. However, in the 80 x 86 architecture, if the page is present, the access
was for writing and the page frame is write-protected (see the earlier section "Handling a Faulty
Address Inside the Address Space"). Thus, the do_wp_page( ) function is always invoked.

我觉得对ARM也是通用的。即是:如果pte_present()==true,那么只有可能一种COW的情况。

请大家轻喷 ^_^

论坛徽章:
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
22 [报告]
发表于 2013-02-04 10:25 |只看该作者

你说的COW跟我的问题没有关系吧....


回复 20# a_kernel_newbie


   

论坛徽章:
0
23 [报告]
发表于 2013-02-04 10:30 |只看该作者
回复 21# chishanmingshen


    你的问题难道不是:什么情况下,会走下面的code?


  
    <---------------------------------------------------------下面这个分支是哪种场景???谢谢!!!
        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;



我回答的帖子是,从ulk3上找到的答案:对于x86,下面这个分支永远不会走到。

论坛徽章:
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
24 [报告]
发表于 2013-02-04 10:35 |只看该作者

my god... 不会吧, 我觉得bboytaiwan解答得挺有道理啊, 你觉得呢...

论坛徽章:
0
25 [报告]
发表于 2013-02-04 10:49 |只看该作者
回复 23# chishanmingshen

taiwai大牛重点解释的是pte_same吧。

   
            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);
        }


这个“防呆”,是什么意思?

另外,pte_same,我觉得还有问题。

论坛徽章:
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
26 [报告]
发表于 2013-02-05 11:16 |只看该作者

没看明白... 呜呼

论坛徽章:
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
27 [报告]
发表于 2013-03-18 20:42 |只看该作者
本帖最后由 chishanmingshen 于 2013-03-18 21:34 编辑

等你回来啊。。。

针对1楼的问题,你的答案是写一个可写页时的tlb invalid(其它cpu在tlb miss时置上的)的情形?

理解对否,请指点啊,谢谢!

回复 13# 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
28 [报告]
发表于 2013-03-21 21:27 |只看该作者
24小时不间断等解答,谢谢~~~

论坛徽章:
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
29 [报告]
发表于 2013-04-13 20:40 |只看该作者
回复 28# junnyg


    哦,x86、arm硬件自动完成tlb缺失填写,但在mips架构中由软件完成。谢谢!

论坛徽章:
0
30 [报告]
发表于 2013-04-29 15:13 |只看该作者
回复 12# chishanmingshen


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的时候...?

/* 有可能在上面entry = *pte;取出entry到if這個statement中間有另外一個process or thread比較早發生page fault
*  並且已經改變了*pte的值。因此有可能造成不same的狀況。而改變*pte有可能包含上面四種faults,和下面這個do_wp_page。
*/

                goto unlock;
        if (flags & FAULT_FLAG_WRITE) {

/* 兩個threads or processes同時發生fault,有可能我這個thread/process跑在後面,在entry=*pte之前另一個prcoess/thread
*  就已經把do_wp_page() fault處理完了,這時候有可能發生pte_write=1的情況(可寫),這時候下面ptep_set_access_flags會是false代表相同。
*  因為另一個thread/process以經幫我們設pte_mkdirty & pte_mkyoung。
* 該做的是把tlb flush掉,也就是下面的else。但感覺也可以不用作,因為另一個process/thread應該會打ipi通知我們做flush tlb的動作。
* 像是arm A15有tlb coherency則完全不用作flush。
*/

                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;
}


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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP