docs/vm: mmu_notifier.txt: convert to ReST format
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
2fcbc41380
commit
16f9f7f924
|
@ -1,7 +1,10 @@
|
||||||
|
.. _mmu_notifier:
|
||||||
|
|
||||||
When do you need to notify inside page table lock ?
|
When do you need to notify inside page table lock ?
|
||||||
|
===================================================
|
||||||
|
|
||||||
When clearing a pte/pmd we are given a choice to notify the event through
|
When clearing a pte/pmd we are given a choice to notify the event through
|
||||||
(notify version of *_clear_flush call mmu_notifier_invalidate_range) under
|
(notify version of \*_clear_flush call mmu_notifier_invalidate_range) under
|
||||||
the page table lock. But that notification is not necessary in all cases.
|
the page table lock. But that notification is not necessary in all cases.
|
||||||
|
|
||||||
For secondary TLB (non CPU TLB) like IOMMU TLB or device TLB (when device use
|
For secondary TLB (non CPU TLB) like IOMMU TLB or device TLB (when device use
|
||||||
|
@ -18,6 +21,7 @@ a page that might now be used by some completely different task.
|
||||||
|
|
||||||
Case B is more subtle. For correctness it requires the following sequence to
|
Case B is more subtle. For correctness it requires the following sequence to
|
||||||
happen:
|
happen:
|
||||||
|
|
||||||
- take page table lock
|
- take page table lock
|
||||||
- clear page table entry and notify ([pmd/pte]p_huge_clear_flush_notify())
|
- clear page table entry and notify ([pmd/pte]p_huge_clear_flush_notify())
|
||||||
- set page table entry to point to new page
|
- set page table entry to point to new page
|
||||||
|
@ -28,58 +32,60 @@ the device.
|
||||||
|
|
||||||
Consider the following scenario (device use a feature similar to ATS/PASID):
|
Consider the following scenario (device use a feature similar to ATS/PASID):
|
||||||
|
|
||||||
Two address addrA and addrB such that |addrA - addrB| >= PAGE_SIZE we assume
|
Two address addrA and addrB such that \|addrA - addrB\| >= PAGE_SIZE we assume
|
||||||
they are write protected for COW (other case of B apply too).
|
they are write protected for COW (other case of B apply too).
|
||||||
|
|
||||||
[Time N] --------------------------------------------------------------------
|
::
|
||||||
CPU-thread-0 {try to write to addrA}
|
|
||||||
CPU-thread-1 {try to write to addrB}
|
[Time N] --------------------------------------------------------------------
|
||||||
CPU-thread-2 {}
|
CPU-thread-0 {try to write to addrA}
|
||||||
CPU-thread-3 {}
|
CPU-thread-1 {try to write to addrB}
|
||||||
DEV-thread-0 {read addrA and populate device TLB}
|
CPU-thread-2 {}
|
||||||
DEV-thread-2 {read addrB and populate device TLB}
|
CPU-thread-3 {}
|
||||||
[Time N+1] ------------------------------------------------------------------
|
DEV-thread-0 {read addrA and populate device TLB}
|
||||||
CPU-thread-0 {COW_step0: {mmu_notifier_invalidate_range_start(addrA)}}
|
DEV-thread-2 {read addrB and populate device TLB}
|
||||||
CPU-thread-1 {COW_step0: {mmu_notifier_invalidate_range_start(addrB)}}
|
[Time N+1] ------------------------------------------------------------------
|
||||||
CPU-thread-2 {}
|
CPU-thread-0 {COW_step0: {mmu_notifier_invalidate_range_start(addrA)}}
|
||||||
CPU-thread-3 {}
|
CPU-thread-1 {COW_step0: {mmu_notifier_invalidate_range_start(addrB)}}
|
||||||
DEV-thread-0 {}
|
CPU-thread-2 {}
|
||||||
DEV-thread-2 {}
|
CPU-thread-3 {}
|
||||||
[Time N+2] ------------------------------------------------------------------
|
DEV-thread-0 {}
|
||||||
CPU-thread-0 {COW_step1: {update page table to point to new page for addrA}}
|
DEV-thread-2 {}
|
||||||
CPU-thread-1 {COW_step1: {update page table to point to new page for addrB}}
|
[Time N+2] ------------------------------------------------------------------
|
||||||
CPU-thread-2 {}
|
CPU-thread-0 {COW_step1: {update page table to point to new page for addrA}}
|
||||||
CPU-thread-3 {}
|
CPU-thread-1 {COW_step1: {update page table to point to new page for addrB}}
|
||||||
DEV-thread-0 {}
|
CPU-thread-2 {}
|
||||||
DEV-thread-2 {}
|
CPU-thread-3 {}
|
||||||
[Time N+3] ------------------------------------------------------------------
|
DEV-thread-0 {}
|
||||||
CPU-thread-0 {preempted}
|
DEV-thread-2 {}
|
||||||
CPU-thread-1 {preempted}
|
[Time N+3] ------------------------------------------------------------------
|
||||||
CPU-thread-2 {write to addrA which is a write to new page}
|
CPU-thread-0 {preempted}
|
||||||
CPU-thread-3 {}
|
CPU-thread-1 {preempted}
|
||||||
DEV-thread-0 {}
|
CPU-thread-2 {write to addrA which is a write to new page}
|
||||||
DEV-thread-2 {}
|
CPU-thread-3 {}
|
||||||
[Time N+3] ------------------------------------------------------------------
|
DEV-thread-0 {}
|
||||||
CPU-thread-0 {preempted}
|
DEV-thread-2 {}
|
||||||
CPU-thread-1 {preempted}
|
[Time N+3] ------------------------------------------------------------------
|
||||||
CPU-thread-2 {}
|
CPU-thread-0 {preempted}
|
||||||
CPU-thread-3 {write to addrB which is a write to new page}
|
CPU-thread-1 {preempted}
|
||||||
DEV-thread-0 {}
|
CPU-thread-2 {}
|
||||||
DEV-thread-2 {}
|
CPU-thread-3 {write to addrB which is a write to new page}
|
||||||
[Time N+4] ------------------------------------------------------------------
|
DEV-thread-0 {}
|
||||||
CPU-thread-0 {preempted}
|
DEV-thread-2 {}
|
||||||
CPU-thread-1 {COW_step3: {mmu_notifier_invalidate_range_end(addrB)}}
|
[Time N+4] ------------------------------------------------------------------
|
||||||
CPU-thread-2 {}
|
CPU-thread-0 {preempted}
|
||||||
CPU-thread-3 {}
|
CPU-thread-1 {COW_step3: {mmu_notifier_invalidate_range_end(addrB)}}
|
||||||
DEV-thread-0 {}
|
CPU-thread-2 {}
|
||||||
DEV-thread-2 {}
|
CPU-thread-3 {}
|
||||||
[Time N+5] ------------------------------------------------------------------
|
DEV-thread-0 {}
|
||||||
CPU-thread-0 {preempted}
|
DEV-thread-2 {}
|
||||||
CPU-thread-1 {}
|
[Time N+5] ------------------------------------------------------------------
|
||||||
CPU-thread-2 {}
|
CPU-thread-0 {preempted}
|
||||||
CPU-thread-3 {}
|
CPU-thread-1 {}
|
||||||
DEV-thread-0 {read addrA from old page}
|
CPU-thread-2 {}
|
||||||
DEV-thread-2 {read addrB from new page}
|
CPU-thread-3 {}
|
||||||
|
DEV-thread-0 {read addrA from old page}
|
||||||
|
DEV-thread-2 {read addrB from new page}
|
||||||
|
|
||||||
So here because at time N+2 the clear page table entry was not pair with a
|
So here because at time N+2 the clear page table entry was not pair with a
|
||||||
notification to invalidate the secondary TLB, the device see the new value for
|
notification to invalidate the secondary TLB, the device see the new value for
|
||||||
|
|
Loading…
Reference in New Issue