lkml.org 
[lkml]   [2015]   [Jul]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 03/15] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page() v2
    Date
    Listener of mm event might not have easy way to get the struct page
    behind an address invalidated with mmu_notifier_invalidate_page()
    function as this happens after the cpu page table have been clear/
    updated. This happens for instance if the listener is storing a dma
    mapping inside its secondary page table. To avoid complex reverse
    dma mapping lookup just pass along a pointer to the page being
    invalidated.

    Changed since v1:
    - English syntax fixes.

    Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
    ---
    drivers/infiniband/core/umem_odp.c | 1 +
    drivers/iommu/amd_iommu_v2.c | 1 +
    drivers/misc/sgi-gru/grutlbpurge.c | 1 +
    drivers/xen/gntdev.c | 1 +
    include/linux/mmu_notifier.h | 6 +++++-
    mm/mmu_notifier.c | 3 ++-
    mm/rmap.c | 4 ++--
    virt/kvm/kvm_main.c | 1 +
    8 files changed, 14 insertions(+), 4 deletions(-)

    diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
    index 58d9a00..0541761 100644
    --- a/drivers/infiniband/core/umem_odp.c
    +++ b/drivers/infiniband/core/umem_odp.c
    @@ -166,6 +166,7 @@ static int invalidate_page_trampoline(struct ib_umem *item, u64 start,
    static void ib_umem_notifier_invalidate_page(struct mmu_notifier *mn,
    struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    struct ib_ucontext *context = container_of(mn, struct ib_ucontext, mn);
    diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
    index 4aa4de6..de3c540 100644
    --- a/drivers/iommu/amd_iommu_v2.c
    +++ b/drivers/iommu/amd_iommu_v2.c
    @@ -385,6 +385,7 @@ static int mn_clear_flush_young(struct mmu_notifier *mn,
    static void mn_invalidate_page(struct mmu_notifier *mn,
    struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    __mn_flush_page(mn, address);
    diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c
    index 44b41b7..c7659b76 100644
    --- a/drivers/misc/sgi-gru/grutlbpurge.c
    +++ b/drivers/misc/sgi-gru/grutlbpurge.c
    @@ -250,6 +250,7 @@ static void gru_invalidate_range_end(struct mmu_notifier *mn,

    static void gru_invalidate_page(struct mmu_notifier *mn, struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
    diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
    index a601f69..3cc52c2 100644
    --- a/drivers/xen/gntdev.c
    +++ b/drivers/xen/gntdev.c
    @@ -485,6 +485,7 @@ static void mn_invl_range_start(struct mmu_notifier *mn,
    static void mn_invl_page(struct mmu_notifier *mn,
    struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    struct mmu_notifier_range range;
    diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
    index 13b4b51..1a20145c 100644
    --- a/include/linux/mmu_notifier.h
    +++ b/include/linux/mmu_notifier.h
    @@ -169,6 +169,7 @@ struct mmu_notifier_ops {
    void (*invalidate_page)(struct mmu_notifier *mn,
    struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event);

    /*
    @@ -287,6 +288,7 @@ extern void __mmu_notifier_change_pte(struct mm_struct *mm,
    enum mmu_event event);
    extern void __mmu_notifier_invalidate_page(struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event);
    extern void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
    struct mmu_notifier_range *range);
    @@ -335,10 +337,11 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm,

    static inline void mmu_notifier_invalidate_page(struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    if (mm_has_notifiers(mm))
    - __mmu_notifier_invalidate_page(mm, address, event);
    + __mmu_notifier_invalidate_page(mm, address, page, event);
    }

    static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm,
    @@ -489,6 +492,7 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm,

    static inline void mmu_notifier_invalidate_page(struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    }
    diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
    index 99fccbd..2ed6d0d 100644
    --- a/mm/mmu_notifier.c
    +++ b/mm/mmu_notifier.c
    @@ -160,6 +160,7 @@ void __mmu_notifier_change_pte(struct mm_struct *mm,

    void __mmu_notifier_invalidate_page(struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    struct mmu_notifier *mn;
    @@ -168,7 +169,7 @@ void __mmu_notifier_invalidate_page(struct mm_struct *mm,
    id = srcu_read_lock(&srcu);
    hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) {
    if (mn->ops->invalidate_page)
    - mn->ops->invalidate_page(mn, mm, address, event);
    + mn->ops->invalidate_page(mn, mm, address, page, event);
    }
    srcu_read_unlock(&srcu, id);
    }
    diff --git a/mm/rmap.c b/mm/rmap.c
    index b1e6eae..65aee96 100644
    --- a/mm/rmap.c
    +++ b/mm/rmap.c
    @@ -891,7 +891,7 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma,
    pte_unmap_unlock(pte, ptl);

    if (ret) {
    - mmu_notifier_invalidate_page(mm, address, MMU_WRITE_BACK);
    + mmu_notifier_invalidate_page(mm, address, page, MMU_WRITE_BACK);
    (*cleaned)++;
    }
    out:
    @@ -1298,7 +1298,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
    out_unmap:
    pte_unmap_unlock(pte, ptl);
    if (ret != SWAP_FAIL && !(flags & TTU_MUNLOCK))
    - mmu_notifier_invalidate_page(mm, address, MMU_MIGRATE);
    + mmu_notifier_invalidate_page(mm, address, page, MMU_MIGRATE);
    out:
    return ret;

    diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
    index 7e79aa8..5f35340 100644
    --- a/virt/kvm/kvm_main.c
    +++ b/virt/kvm/kvm_main.c
    @@ -260,6 +260,7 @@ static inline struct kvm *mmu_notifier_to_kvm(struct mmu_notifier *mn)
    static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
    struct mm_struct *mm,
    unsigned long address,
    + struct page *page,
    enum mmu_event event)
    {
    struct kvm *kvm = mmu_notifier_to_kvm(mn);
    --
    1.9.3


    \
     
     \ /
      Last update: 2015-07-17 21:21    [W:4.009 / U:0.252 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site