mm: move tlb_flush_pending inline helpers to mm_inline.h
authorArnd Bergmann <arnd@arndb.de>
Fri, 14 Jan 2022 22:06:10 +0000 (14:06 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 15 Jan 2022 14:30:27 +0000 (16:30 +0200)
linux/mm_types.h should only define structure definitions, to make it
cheap to include elsewhere.  The atomic_t helper function definitions
are particularly large, so it's better to move the helpers using those
into the existing linux/mm_inline.h and only include that where needed.

As a follow-up, we may want to go through all the indirect includes in
mm_types.h and reduce them as much as possible.

Link: https://lkml.kernel.org/r/20211207125710.2503446-2-arnd@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Colin Cross <ccross@google.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Peter Xu <peterx@redhat.com>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Eric Biederman <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/x86/include/asm/pgtable.h
include/linux/mm.h
include/linux/mm_inline.h
include/linux/mm_types.h
mm/ksm.c
mm/mapping_dirty_helpers.c
mm/memory.c
mm/mmu_gather.c
mm/pgtable-generic.c

index 448cd01..5196958 100644 (file)
@@ -752,7 +752,7 @@ static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
                return true;
 
        if ((pte_flags(a) & _PAGE_PROTNONE) &&
-                       mm_tlb_flush_pending(mm))
+                       atomic_read(&mm->tlb_flush_pending))
                return true;
 
        return false;
index 7000442..c17e5cf 100644 (file)
@@ -424,51 +424,6 @@ extern unsigned int kobjsize(const void *objp);
  */
 extern pgprot_t protection_map[16];
 
-/**
- * enum fault_flag - Fault flag definitions.
- * @FAULT_FLAG_WRITE: Fault was a write fault.
- * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
- * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
- * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_lock and wait when retrying.
- * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
- * @FAULT_FLAG_TRIED: The fault has been tried once.
- * @FAULT_FLAG_USER: The fault originated in userspace.
- * @FAULT_FLAG_REMOTE: The fault is not for current task/mm.
- * @FAULT_FLAG_INSTRUCTION: The fault was during an instruction fetch.
- * @FAULT_FLAG_INTERRUPTIBLE: The fault can be interrupted by non-fatal signals.
- *
- * About @FAULT_FLAG_ALLOW_RETRY and @FAULT_FLAG_TRIED: we can specify
- * whether we would allow page faults to retry by specifying these two
- * fault flags correctly.  Currently there can be three legal combinations:
- *
- * (a) ALLOW_RETRY and !TRIED:  this means the page fault allows retry, and
- *                              this is the first try
- *
- * (b) ALLOW_RETRY and TRIED:   this means the page fault allows retry, and
- *                              we've already tried at least once
- *
- * (c) !ALLOW_RETRY and !TRIED: this means the page fault does not allow retry
- *
- * The unlisted combination (!ALLOW_RETRY && TRIED) is illegal and should never
- * be used.  Note that page faults can be allowed to retry for multiple times,
- * in which case we'll have an initial fault with flags (a) then later on
- * continuous faults with flags (b).  We should always try to detect pending
- * signals before a retry to make sure the continuous page faults can still be
- * interrupted if necessary.
- */
-enum fault_flag {
-       FAULT_FLAG_WRITE =              1 << 0,
-       FAULT_FLAG_MKWRITE =            1 << 1,
-       FAULT_FLAG_ALLOW_RETRY =        1 << 2,
-       FAULT_FLAG_RETRY_NOWAIT =       1 << 3,
-       FAULT_FLAG_KILLABLE =           1 << 4,
-       FAULT_FLAG_TRIED =              1 << 5,
-       FAULT_FLAG_USER =               1 << 6,
-       FAULT_FLAG_REMOTE =             1 << 7,
-       FAULT_FLAG_INSTRUCTION =        1 << 8,
-       FAULT_FLAG_INTERRUPTIBLE =      1 << 9,
-};
-
 /*
  * The default fault flags that should be used by most of the
  * arch-specific page fault handlers.
index 47d96d2..b725839 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef LINUX_MM_INLINE_H
 #define LINUX_MM_INLINE_H
 
+#include <linux/atomic.h>
 #include <linux/huge_mm.h>
 #include <linux/swap.h>
 #include <linux/string.h>
@@ -185,4 +186,89 @@ static inline bool is_same_vma_anon_name(struct vm_area_struct *vma,
 }
 #endif  /* CONFIG_ANON_VMA_NAME */
 
+static inline void init_tlb_flush_pending(struct mm_struct *mm)
+{
+       atomic_set(&mm->tlb_flush_pending, 0);
+}
+
+static inline void inc_tlb_flush_pending(struct mm_struct *mm)
+{
+       atomic_inc(&mm->tlb_flush_pending);
+       /*
+        * The only time this value is relevant is when there are indeed pages
+        * to flush. And we'll only flush pages after changing them, which
+        * requires the PTL.
+        *
+        * So the ordering here is:
+        *
+        *      atomic_inc(&mm->tlb_flush_pending);
+        *      spin_lock(&ptl);
+        *      ...
+        *      set_pte_at();
+        *      spin_unlock(&ptl);
+        *
+        *                              spin_lock(&ptl)
+        *                              mm_tlb_flush_pending();
+        *                              ....
+        *                              spin_unlock(&ptl);
+        *
+        *      flush_tlb_range();
+        *      atomic_dec(&mm->tlb_flush_pending);
+        *
+        * Where the increment if constrained by the PTL unlock, it thus
+        * ensures that the increment is visible if the PTE modification is
+        * visible. After all, if there is no PTE modification, nobody cares
+        * about TLB flushes either.
+        *
+        * This very much relies on users (mm_tlb_flush_pending() and
+        * mm_tlb_flush_nested()) only caring about _specific_ PTEs (and
+        * therefore specific PTLs), because with SPLIT_PTE_PTLOCKS and RCpc
+        * locks (PPC) the unlock of one doesn't order against the lock of
+        * another PTL.
+        *
+        * The decrement is ordered by the flush_tlb_range(), such that
+        * mm_tlb_flush_pending() will not return false unless all flushes have
+        * completed.
+        */
+}
+
+static inline void dec_tlb_flush_pending(struct mm_struct *mm)
+{
+       /*
+        * See inc_tlb_flush_pending().
+        *
+        * This cannot be smp_mb__before_atomic() because smp_mb() simply does
+        * not order against TLB invalidate completion, which is what we need.
+        *
+        * Therefore we must rely on tlb_flush_*() to guarantee order.
+        */
+       atomic_dec(&mm->tlb_flush_pending);
+}
+
+static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
+{
+       /*
+        * Must be called after having acquired the PTL; orders against that
+        * PTLs release and therefore ensures that if we observe the modified
+        * PTE we must also observe the increment from inc_tlb_flush_pending().
+        *
+        * That is, it only guarantees to return true if there is a flush
+        * pending for _this_ PTL.
+        */
+       return atomic_read(&mm->tlb_flush_pending);
+}
+
+static inline bool mm_tlb_flush_nested(struct mm_struct *mm)
+{
+       /*
+        * Similar to mm_tlb_flush_pending(), we must have acquired the PTL
+        * for which there is a TLB flush pending in order to guarantee
+        * we've seen both that PTE modification and the increment.
+        *
+        * (no requirement on actually still holding the PTL, that is irrelevant)
+        */
+       return atomic_read(&mm->tlb_flush_pending) > 1;
+}
+
+
 #endif
index 4d5fb84..6a89f12 100644 (file)
@@ -692,90 +692,6 @@ extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm);
 extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm);
 extern void tlb_finish_mmu(struct mmu_gather *tlb);
 
-static inline void init_tlb_flush_pending(struct mm_struct *mm)
-{
-       atomic_set(&mm->tlb_flush_pending, 0);
-}
-
-static inline void inc_tlb_flush_pending(struct mm_struct *mm)
-{
-       atomic_inc(&mm->tlb_flush_pending);
-       /*
-        * The only time this value is relevant is when there are indeed pages
-        * to flush. And we'll only flush pages after changing them, which
-        * requires the PTL.
-        *
-        * So the ordering here is:
-        *
-        *      atomic_inc(&mm->tlb_flush_pending);
-        *      spin_lock(&ptl);
-        *      ...
-        *      set_pte_at();
-        *      spin_unlock(&ptl);
-        *
-        *                              spin_lock(&ptl)
-        *                              mm_tlb_flush_pending();
-        *                              ....
-        *                              spin_unlock(&ptl);
-        *
-        *      flush_tlb_range();
-        *      atomic_dec(&mm->tlb_flush_pending);
-        *
-        * Where the increment if constrained by the PTL unlock, it thus
-        * ensures that the increment is visible if the PTE modification is
-        * visible. After all, if there is no PTE modification, nobody cares
-        * about TLB flushes either.
-        *
-        * This very much relies on users (mm_tlb_flush_pending() and
-        * mm_tlb_flush_nested()) only caring about _specific_ PTEs (and
-        * therefore specific PTLs), because with SPLIT_PTE_PTLOCKS and RCpc
-        * locks (PPC) the unlock of one doesn't order against the lock of
-        * another PTL.
-        *
-        * The decrement is ordered by the flush_tlb_range(), such that
-        * mm_tlb_flush_pending() will not return false unless all flushes have
-        * completed.
-        */
-}
-
-static inline void dec_tlb_flush_pending(struct mm_struct *mm)
-{
-       /*
-        * See inc_tlb_flush_pending().
-        *
-        * This cannot be smp_mb__before_atomic() because smp_mb() simply does
-        * not order against TLB invalidate completion, which is what we need.
-        *
-        * Therefore we must rely on tlb_flush_*() to guarantee order.
-        */
-       atomic_dec(&mm->tlb_flush_pending);
-}
-
-static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
-{
-       /*
-        * Must be called after having acquired the PTL; orders against that
-        * PTLs release and therefore ensures that if we observe the modified
-        * PTE we must also observe the increment from inc_tlb_flush_pending().
-        *
-        * That is, it only guarantees to return true if there is a flush
-        * pending for _this_ PTL.
-        */
-       return atomic_read(&mm->tlb_flush_pending);
-}
-
-static inline bool mm_tlb_flush_nested(struct mm_struct *mm)
-{
-       /*
-        * Similar to mm_tlb_flush_pending(), we must have acquired the PTL
-        * for which there is a TLB flush pending in order to guarantee
-        * we've seen both that PTE modification and the increment.
-        *
-        * (no requirement on actually still holding the PTL, that is irrelevant)
-        */
-       return atomic_read(&mm->tlb_flush_pending) > 1;
-}
-
 struct vm_fault;
 
 /**
@@ -890,4 +806,49 @@ typedef struct {
        unsigned long val;
 } swp_entry_t;
 
+/**
+ * enum fault_flag - Fault flag definitions.
+ * @FAULT_FLAG_WRITE: Fault was a write fault.
+ * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
+ * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
+ * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_lock and wait when retrying.
+ * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
+ * @FAULT_FLAG_TRIED: The fault has been tried once.
+ * @FAULT_FLAG_USER: The fault originated in userspace.
+ * @FAULT_FLAG_REMOTE: The fault is not for current task/mm.
+ * @FAULT_FLAG_INSTRUCTION: The fault was during an instruction fetch.
+ * @FAULT_FLAG_INTERRUPTIBLE: The fault can be interrupted by non-fatal signals.
+ *
+ * About @FAULT_FLAG_ALLOW_RETRY and @FAULT_FLAG_TRIED: we can specify
+ * whether we would allow page faults to retry by specifying these two
+ * fault flags correctly.  Currently there can be three legal combinations:
+ *
+ * (a) ALLOW_RETRY and !TRIED:  this means the page fault allows retry, and
+ *                              this is the first try
+ *
+ * (b) ALLOW_RETRY and TRIED:   this means the page fault allows retry, and
+ *                              we've already tried at least once
+ *
+ * (c) !ALLOW_RETRY and !TRIED: this means the page fault does not allow retry
+ *
+ * The unlisted combination (!ALLOW_RETRY && TRIED) is illegal and should never
+ * be used.  Note that page faults can be allowed to retry for multiple times,
+ * in which case we'll have an initial fault with flags (a) then later on
+ * continuous faults with flags (b).  We should always try to detect pending
+ * signals before a retry to make sure the continuous page faults can still be
+ * interrupted if necessary.
+ */
+enum fault_flag {
+       FAULT_FLAG_WRITE =              1 << 0,
+       FAULT_FLAG_MKWRITE =            1 << 1,
+       FAULT_FLAG_ALLOW_RETRY =        1 << 2,
+       FAULT_FLAG_RETRY_NOWAIT =       1 << 3,
+       FAULT_FLAG_KILLABLE =           1 << 4,
+       FAULT_FLAG_TRIED =              1 << 5,
+       FAULT_FLAG_USER =               1 << 6,
+       FAULT_FLAG_REMOTE =             1 << 7,
+       FAULT_FLAG_INSTRUCTION =        1 << 8,
+       FAULT_FLAG_INTERRUPTIBLE =      1 << 9,
+};
+
 #endif /* _LINUX_MM_TYPES_H */
index 0662093..f34476a 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -15,6 +15,7 @@
 
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/mm_inline.h>
 #include <linux/fs.h>
 #include <linux/mman.h>
 #include <linux/sched.h>
index ea734f2..1b0ab8f 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/hugetlb.h>
 #include <linux/bitops.h>
 #include <linux/mmu_notifier.h>
+#include <linux/mm_inline.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
index 8f1de81..bc80d4e 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <linux/kernel_stat.h>
 #include <linux/mm.h>
+#include <linux/mm_inline.h>
 #include <linux/sched/mm.h>
 #include <linux/sched/coredump.h>
 #include <linux/sched/numa_balancing.h>
index 1b98374..afb7185 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/kernel.h>
 #include <linux/mmdebug.h>
 #include <linux/mm_types.h>
+#include <linux/mm_inline.h>
 #include <linux/pagemap.h>
 #include <linux/rcupdate.h>
 #include <linux/smp.h>
index 4e640ba..6523fda 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/pagemap.h>
 #include <linux/hugetlb.h>
 #include <linux/pgtable.h>
+#include <linux/mm_inline.h>
 #include <asm/tlb.h>
 
 /*