Commit 16f9f7f9 authored by Mike Rapoport's avatar Mike Rapoport Committed by Jonathan Corbet

docs/vm: mmu_notifier.txt: convert to ReST format

Signed-off-by: default avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
parent 2fcbc413
.. _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. ...@@ -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. ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment