在 PTE 中设置脏标志时,x86_64 CPU 会注意到页表条目已更改为不存在吗?

问题描述 投票:0回答:1

有一个场景如下:

PAGE

a
的pte
A
设置以下字段:

  • BIT(0) 存在
  • BIT(1) 可写
  • BIT(M-1,12)页框
  • 脏标志未设置
CPU0                                     CPU1
                                         cached translation information 
                                         about the PTE a (TLB)
modify pte a present flags to 0.
(not exec tlb shootdown)                 
                                         write a virtual address translated by pte a

现在,这个写操作会正常执行还是会导致页面错误?


该问题来自 Linux 内核提交。基于代码逻辑 commit,我倾向于认为上面提到的情况会导致page 故障。

有关此 COMMIT 的信息:

commit d950c9477d51f0cefc2ed3cf76e695d46af0d9c1
Author: Mel Gorman <[email protected]>
Date:   Fri Sep 4 15:47:35 2015 -0700

    mm: defer flush of writable TLB entries

这里不再展示代码,大概的逻辑是:

kswapd
进行内存回收时,发现某个页面可以 被回收。首先,取消映射。取消映射操作会修改页表 结构体修改后,需要执行tlb flash(可能 执行 tlb shotdown)但是,内核可能会延迟 tlb 刷新操作 命令执行批量刷新(因为 tlb 击落需要发送 ipi、批量 刷新会将发送的 ipi 数量减少到 1)。但需要确定 在清除PTE之前PTE是否脏了,

如果脏了,需要立即冲水 如果不脏,可以批量处理

page_out()

后冲洗

我想可能有以下几个原因:

如果页面是脏的,则表明最近有人访问过该页面, 如果没有flush tlb remote,其他CPU可能仍然可以访问它 通常不产生 PF。但是,如果页面没有脏,之后 清除pte,即使其他CPU使用旧的tlb来访问它(脏标志 在旧的 tlb 中为 0),脏标志将被更新并进行全面检查 生成 PF。 (以上是我自己的理解,不能保证一定正确) 正确)。

如果将脏位1修改为0,但不刷新tlb。这种情况是 英特尔 SDM 中描述

If software modifies a paging-structure entry that identifies the final
 physical address for a linear address(either a PTE or a paging-structure
entry in which the PS flag is 1) to change the dirty flag from 1 to 0,
failure to perform an invalidation may result in the processor not setting
 that bit in response to a subsequent write to a linear address whose
translation uses the entry. Software cannot interpret the bit being clear as
an indication that such a write has not occurred

但是对于开头提到的问题,并不是 在英特尔 SDM 中找到。

x86-64 cpu-architecture paging tlb page-tables
1个回答
0
投票

Peter,我认为你是对的,但我在Intel SDM中没有找到任何相关说明。英特尔 SDM 中仅提供以下内容。

If software modifies a paging-structure entry that identifies the final
 physical address for a linear address(either a PTE or a paging-structure 
entry in which the PS flag is 1) to change the dirty flag from 1 to 0, 
failure to perform an invalidation may result in the processor not setting
 that bit in response to a subsequent write to a linear address whose 
translation uses the entry. Software cannot interpret the bit being clear as 
an indication that such a write has not occurred

但是,这并没有最终修改PTE。如果有必要修改PTE(比如脏位),我也认为应该进行全面检查。

我认为Linux内核代码具有使用上述的特点。

承诺:

commit d950c9477d51f0cefc2ed3cf76e695d46af0d9c1
Author: Mel Gorman <[email protected]>
Date:   Fri Sep 4 15:47:35 2015 -0700

    mm: defer flush of writable TLB entries

这里不再展示代码,大概的逻辑是:

取消映射页面时,首先修改pte(清除pte),如果页面脏了,立即刷新远程tlb(tlb shotdown)。如果页面不是,可以先进行

pageout()
,然后执行flush。

如果页面是脏的,说明最近有人访问过该页面,如果没有flush tlb remote,其他CPU可能仍然可以正常访问,而不会产生PF。但如果该页不脏,则清除pte后,即使其他CPU使用old tlb访问它(old tlb中的dirty标志为0),也会更新dirty标志并进行全量检查,生成PF。 (以上是我自己的理解,不能保证正确)。

谢谢,彼得。

© www.soinside.com 2019 - 2024. All rights reserved.