Re: [PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
On Thu, 21 May 2015, j.gli...@gmail.com wrote: > From: Jérôme Glisse > > Listener of mm event might not have easy way to get the struct page > behind and address invalidated with mmu_notifier_invalidate_page() s/behind and address/behind an address/ > 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. > > Signed-off-by: Jérôme Glisse > --- > 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 8f7f845..d10dd88 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 0e8aa12..90693ce 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 ada3ed1..283ad26 100644 > --- a/include/linux/mmu_notifier.h > +++ b/include/linux/mmu_notifier.h > @@ -172,6 +172,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); > > /* > @@ -290,6 +291,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); > @@ -338,10 +340,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,
Re: [PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
On Thu, 21 May 2015, j.gli...@gmail.com wrote: From: Jérôme Glisse jgli...@redhat.com Listener of mm event might not have easy way to get the struct page behind and address invalidated with mmu_notifier_invalidate_page() s/behind and address/behind an address/ 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. Signed-off-by: Jérôme Glisse jgli...@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 8f7f845..d10dd88 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 0e8aa12..90693ce 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 ada3ed1..283ad26 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -172,6 +172,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); /* @@ -290,6 +291,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); @@ -338,10 +340,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,
Re: [PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
On Wed, May 27, 2015 at 10:47:44AM +0530, Aneesh Kumar K.V wrote: > j.gli...@gmail.com writes: > > > From: Jérôme Glisse > > > > Listener of mm event might not have easy way to get the struct page > > behind and 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. > > . > > > diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h > > index ada3ed1..283ad26 100644 > > --- a/include/linux/mmu_notifier.h > > +++ b/include/linux/mmu_notifier.h > > @@ -172,6 +172,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); > > > > How do we handle this w.r.t invalidate_range ? With range invalidation the CPU page table is still reliable when invalidate_range_start() callback happen. So we can lookup the CPU page table to get the page backing the address. Cheers, Jérôme -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
On Wed, May 27, 2015 at 10:47:44AM +0530, Aneesh Kumar K.V wrote: j.gli...@gmail.com writes: From: Jérôme Glisse jgli...@redhat.com Listener of mm event might not have easy way to get the struct page behind and 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. . diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index ada3ed1..283ad26 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -172,6 +172,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); How do we handle this w.r.t invalidate_range ? With range invalidation the CPU page table is still reliable when invalidate_range_start() callback happen. So we can lookup the CPU page table to get the page backing the address. Cheers, Jérôme -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
j.gli...@gmail.com writes: > From: Jérôme Glisse > > Listener of mm event might not have easy way to get the struct page > behind and 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. . > diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h > index ada3ed1..283ad26 100644 > --- a/include/linux/mmu_notifier.h > +++ b/include/linux/mmu_notifier.h > @@ -172,6 +172,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); > How do we handle this w.r.t invalidate_range ? -aneesh -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
j.gli...@gmail.com writes: From: Jérôme Glisse jgli...@redhat.com Listener of mm event might not have easy way to get the struct page behind and 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. . diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index ada3ed1..283ad26 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -172,6 +172,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); How do we handle this w.r.t invalidate_range ? -aneesh -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
From: Jérôme Glisse Listener of mm event might not have easy way to get the struct page behind and 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. Signed-off-by: Jérôme Glisse --- 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 8f7f845..d10dd88 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 0e8aa12..90693ce 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 ada3ed1..283ad26 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -172,6 +172,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); /* @@ -290,6 +291,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); @@ -338,10 +340,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, @@ -492,6 +495,7 @@ static inline void mmu_notifier_change_pte(struct
[PATCH 03/36] mmu_notifier: pass page pointer to mmu_notifier_invalidate_page()
From: Jérôme Glisse jgli...@redhat.com Listener of mm event might not have easy way to get the struct page behind and 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. Signed-off-by: Jérôme Glisse jgli...@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 8f7f845..d10dd88 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 0e8aa12..90693ce 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 ada3ed1..283ad26 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -172,6 +172,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); /* @@ -290,6 +291,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); @@ -338,10 +340,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, @@ -492,6 +495,7 @@ static inline