Message ID | 20191028201032.6352-2-jgg@ziepe.ca (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Consolidate the mmu notifier interval_tree and locking | expand |
On 10/28/19 1:10 PM, Jason Gunthorpe wrote: > From: Jason Gunthorpe <jgg@mellanox.com> > > Now that we have KERNEL_HEADER_TEST all headers are generally compile > tested, so relying on makefile tricks to avoid compiling code that depends > on CONFIG_MMU_NOTIFIER is more annoying. > > Instead follow the usual pattern and provide most of the header with only > the functions stubbed out when CONFIG_MMU_NOTIFIER is disabled. This > ensures code compiles no matter what the config setting is. > > While here, struct mmu_notifier_mm is private to mmu_notifier.c, move it. and correct a minor spelling error in a comment. Good. :) > > Reviewed-by: Jérôme Glisse <jglisse@redhat.com> > Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> > --- > include/linux/mmu_notifier.h | 46 +++++++++++++----------------------- > mm/mmu_notifier.c | 13 ++++++++++ > 2 files changed, 30 insertions(+), 29 deletions(-) > Because this is correct as-is, you can add: Reviewed-by: John Hubbard <jhubbard@nvidia.com> ...whether or not you take the following recommendation, which is: you've only done part of the job of making struct mmu_notifier_mm private to mmu_notifier.c. There's more: * struct mmu_notifier_mm is referred to in two places now: mm_types.h and (still) mmu_notifier.h. Therefore: a) Move the last two traces of it out of mmu_notifier.h, and b) Put a forward declaration in mm_types.h, which is where it belongs because that's where it's referred to. So if you apply this incremental patch on top, I think it's where you want to be: diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 2222fa795284..df93a3cc0da9 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -25,6 +25,7 @@ struct address_space; struct mem_cgroup; +struct mmu_notifier_mm; /* * Each physical page in the system has a struct page associated with diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 51b92ba013dd..84efd2c51f5c 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -8,7 +8,6 @@ #include <linux/srcu.h> #include <linux/interval_tree.h> -struct mmu_notifier_mm; struct mmu_notifier; struct mmu_notifier_range; struct mmu_range_notifier; @@ -263,10 +262,7 @@ struct mmu_notifier_range { enum mmu_notifier_event event; }; -static inline int mm_has_notifiers(struct mm_struct *mm) -{ - return unlikely(mm->mmu_notifier_mm); -} +int mm_has_notifiers(struct mm_struct *mm); struct mmu_notifier *mmu_notifier_get_locked(const struct mmu_notifier_ops *ops, struct mm_struct *mm); @@ -477,10 +473,7 @@ static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, __mmu_notifier_invalidate_range(mm, start, end); } -static inline void mmu_notifier_mm_init(struct mm_struct *mm) -{ - mm->mmu_notifier_mm = NULL; -} +void mmu_notifier_mm_init(struct mm_struct *mm); static inline void mmu_notifier_mm_destroy(struct mm_struct *mm) { diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 2b7485919ecf..107f9406a92d 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -47,6 +47,16 @@ struct mmu_notifier_mm { struct hlist_head deferred_list; }; +int mm_has_notifiers(struct mm_struct *mm) +{ + return unlikely(mm->mmu_notifier_mm); +} + +void mmu_notifier_mm_init(struct mm_struct *mm) +{ + mm->mmu_notifier_mm = NULL; +} + /* * This is a collision-retry read-side/write-side 'lock', a lot like a * seqcount, however this allows multiple write-sides to hold it at thanks, John Hubbard NVIDIA > diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h > index 1bd8e6a09a3c27..12bd603d318ce7 100644 > --- a/include/linux/mmu_notifier.h > +++ b/include/linux/mmu_notifier.h > @@ -7,8 +7,9 @@ > #include <linux/mm_types.h> > #include <linux/srcu.h> > > +struct mmu_notifier_mm; > struct mmu_notifier; > -struct mmu_notifier_ops; > +struct mmu_notifier_range; > > /** > * enum mmu_notifier_event - reason for the mmu notifier callback > @@ -40,36 +41,8 @@ enum mmu_notifier_event { > MMU_NOTIFY_SOFT_DIRTY, > }; > > -#ifdef CONFIG_MMU_NOTIFIER > - > -#ifdef CONFIG_LOCKDEP > -extern struct lockdep_map __mmu_notifier_invalidate_range_start_map; > -#endif > - > -/* > - * The mmu notifier_mm structure is allocated and installed in > - * mm->mmu_notifier_mm inside the mm_take_all_locks() protected > - * critical section and it's released only when mm_count reaches zero > - * in mmdrop(). > - */ > -struct mmu_notifier_mm { > - /* all mmu notifiers registerd in this mm are queued in this list */ > - struct hlist_head list; > - /* to serialize the list modifications and hlist_unhashed */ > - spinlock_t lock; > -}; > - > #define MMU_NOTIFIER_RANGE_BLOCKABLE (1 << 0) > > -struct mmu_notifier_range { > - struct vm_area_struct *vma; > - struct mm_struct *mm; > - unsigned long start; > - unsigned long end; > - unsigned flags; > - enum mmu_notifier_event event; > -}; > - > struct mmu_notifier_ops { > /* > * Called either by mmu_notifier_unregister or when the mm is > @@ -249,6 +222,21 @@ struct mmu_notifier { > unsigned int users; > }; > > +#ifdef CONFIG_MMU_NOTIFIER > + > +#ifdef CONFIG_LOCKDEP > +extern struct lockdep_map __mmu_notifier_invalidate_range_start_map; > +#endif > + > +struct mmu_notifier_range { > + struct vm_area_struct *vma; > + struct mm_struct *mm; > + unsigned long start; > + unsigned long end; > + unsigned flags; > + enum mmu_notifier_event event; > +}; > + > static inline int mm_has_notifiers(struct mm_struct *mm) > { > return unlikely(mm->mmu_notifier_mm); > diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c > index 7fde88695f35d6..367670cfd02b7b 100644 > --- a/mm/mmu_notifier.c > +++ b/mm/mmu_notifier.c > @@ -27,6 +27,19 @@ struct lockdep_map __mmu_notifier_invalidate_range_start_map = { > }; > #endif > > +/* > + * The mmu notifier_mm structure is allocated and installed in > + * mm->mmu_notifier_mm inside the mm_take_all_locks() protected > + * critical section and it's released only when mm_count reaches zero > + * in mmdrop(). > + */ > +struct mmu_notifier_mm { > + /* all mmu notifiers registered in this mm are queued in this list */ > + struct hlist_head list; > + /* to serialize the list modifications and hlist_unhashed */ > + spinlock_t lock; > +}; > + > /* > * This function can't run concurrently against mmu_notifier_register > * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap >
On Tue, Nov 05, 2019 at 01:23:46PM -0800, John Hubbard wrote: > On 10/28/19 1:10 PM, Jason Gunthorpe wrote: > > From: Jason Gunthorpe <jgg@mellanox.com> > > > > Now that we have KERNEL_HEADER_TEST all headers are generally compile > > tested, so relying on makefile tricks to avoid compiling code that depends > > on CONFIG_MMU_NOTIFIER is more annoying. > > > > Instead follow the usual pattern and provide most of the header with only > > the functions stubbed out when CONFIG_MMU_NOTIFIER is disabled. This > > ensures code compiles no matter what the config setting is. > > > > While here, struct mmu_notifier_mm is private to mmu_notifier.c, move it. > > and correct a minor spelling error in a comment. Good. :) > > > > > Reviewed-by: Jérôme Glisse <jglisse@redhat.com> > > Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> > > include/linux/mmu_notifier.h | 46 +++++++++++++----------------------- > > mm/mmu_notifier.c | 13 ++++++++++ > > 2 files changed, 30 insertions(+), 29 deletions(-) > > > > Because this is correct as-is, you can add: > > Reviewed-by: John Hubbard <jhubbard@nvidia.com> > Thanks > diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c > index 2b7485919ecf..107f9406a92d 100644 > +++ b/mm/mmu_notifier.c > @@ -47,6 +47,16 @@ struct mmu_notifier_mm { > struct hlist_head deferred_list; > }; > > +int mm_has_notifiers(struct mm_struct *mm) > +{ > + return unlikely(mm->mmu_notifier_mm); > +} This inline is performance sensitive, it needs to stay inlined.. Jason
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 1bd8e6a09a3c27..12bd603d318ce7 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -7,8 +7,9 @@ #include <linux/mm_types.h> #include <linux/srcu.h> +struct mmu_notifier_mm; struct mmu_notifier; -struct mmu_notifier_ops; +struct mmu_notifier_range; /** * enum mmu_notifier_event - reason for the mmu notifier callback @@ -40,36 +41,8 @@ enum mmu_notifier_event { MMU_NOTIFY_SOFT_DIRTY, }; -#ifdef CONFIG_MMU_NOTIFIER - -#ifdef CONFIG_LOCKDEP -extern struct lockdep_map __mmu_notifier_invalidate_range_start_map; -#endif - -/* - * The mmu notifier_mm structure is allocated and installed in - * mm->mmu_notifier_mm inside the mm_take_all_locks() protected - * critical section and it's released only when mm_count reaches zero - * in mmdrop(). - */ -struct mmu_notifier_mm { - /* all mmu notifiers registerd in this mm are queued in this list */ - struct hlist_head list; - /* to serialize the list modifications and hlist_unhashed */ - spinlock_t lock; -}; - #define MMU_NOTIFIER_RANGE_BLOCKABLE (1 << 0) -struct mmu_notifier_range { - struct vm_area_struct *vma; - struct mm_struct *mm; - unsigned long start; - unsigned long end; - unsigned flags; - enum mmu_notifier_event event; -}; - struct mmu_notifier_ops { /* * Called either by mmu_notifier_unregister or when the mm is @@ -249,6 +222,21 @@ struct mmu_notifier { unsigned int users; }; +#ifdef CONFIG_MMU_NOTIFIER + +#ifdef CONFIG_LOCKDEP +extern struct lockdep_map __mmu_notifier_invalidate_range_start_map; +#endif + +struct mmu_notifier_range { + struct vm_area_struct *vma; + struct mm_struct *mm; + unsigned long start; + unsigned long end; + unsigned flags; + enum mmu_notifier_event event; +}; + static inline int mm_has_notifiers(struct mm_struct *mm) { return unlikely(mm->mmu_notifier_mm); diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 7fde88695f35d6..367670cfd02b7b 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -27,6 +27,19 @@ struct lockdep_map __mmu_notifier_invalidate_range_start_map = { }; #endif +/* + * The mmu notifier_mm structure is allocated and installed in + * mm->mmu_notifier_mm inside the mm_take_all_locks() protected + * critical section and it's released only when mm_count reaches zero + * in mmdrop(). + */ +struct mmu_notifier_mm { + /* all mmu notifiers registered in this mm are queued in this list */ + struct hlist_head list; + /* to serialize the list modifications and hlist_unhashed */ + spinlock_t lock; +}; + /* * This function can't run concurrently against mmu_notifier_register * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap