History

mm: do page fault accounting in handle_mm_fault

Patch series "mm: Page fault accounting cleanups", v5. This is v5 of the pf accounting cleanup series. It originates from Gerald Schaefer's report on an issue a week ago regarding to incorrect page fault accountings for retried page fault after commit 4064b9827063 ("mm: allow VM_FAULT_RETRY for multiple times"): https://lore.kernel.org/lkml/20200610174811.44b94525@thinkpad/ What this series did: - Correct page fault accounting: we do accounting for a page fault (no matter whether it's from #PF handling, or gup, or anything else) only with the one that completed the fault. For example, page fault retries should not be counted in page fault counters. Same to the perf events. - Unify definition of PERF_COUNT_SW_PAGE_FAULTS: currently this perf event is used in an adhoc way across different archs. Case (1): for many archs it's done at the entry of a page fault handler, so that it will also cover e.g. errornous faults. Case (2): for some other archs, it is only accounted when the page fault is resolved successfully. Case (3): there're still quite some archs that have not enabled this perf event. Since this series will touch merely all the archs, we unify this perf event to always follow case (1), which is the one that makes most sense. And since we moved the accounting into handle_mm_fault, the other two MAJ/MIN perf events are well taken care of naturally. - Unify definition of "major faults": the definition of "major fault" is slightly changed when used in accounting (not VM_FAULT_MAJOR). More information in patch 1. - Always account the page fault onto the one that triggered the page fault. This does not matter much for #PF handlings, but mostly for gup. More information on this in patch 25. Patchset layout: Patch 1: Introduced the accounting in handle_mm_fault(), not enabled. Patch 2-23: Enable the new accounting for arch #PF handlers one by one. Patch 24: Enable the new accounting for the rest outliers (gup, iommu, etc.) Patch 25: Cleanup GUP task_struct pointer since it's not needed any more This patch (of 25): This is a preparation patch to move page fault accountings into the general code in handle_mm_fault(). This includes both the per task flt_maj/flt_min counters, and the major/minor page fault perf events. To do this, the pt_regs pointer is passed into handle_mm_fault(). PERF_COUNT_SW_PAGE_FAULTS should still be kept in per-arch page fault handlers. So far, all the pt_regs pointer that passed into handle_mm_fault() is NULL, which means this patch should have no intented functional change.

Peter Xu committed 6 years ago

Commit bce617e1 parent ed03d9231 files · +103 −34Browse files

Unified · Split

31 files
  1. arch/alpha/mm/fault.c +1 −1
  2. arch/arc/mm/fault.c +1 −1
  3. arch/arm/mm/fault.c +1 −1
  4. arch/arm64/mm/fault.c +1 −1
  5. arch/csky/mm/fault.c +2 −1
  6. arch/hexagon/mm/vm_fault.c +1 −1
  7. arch/ia64/mm/fault.c +1 −1
  8. arch/m68k/mm/fault.c +1 −1
  9. arch/microblaze/mm/fault.c +1 −1
  10. arch/mips/mm/fault.c +1 −1
  11. arch/nds32/mm/fault.c +1 −1
  12. arch/nios2/mm/fault.c +1 −1
  13. arch/openrisc/mm/fault.c +1 −1
  14. arch/parisc/mm/fault.c +1 −1
  15. arch/powerpc/mm/copro_fault.c +1 −1
  16. arch/powerpc/mm/fault.c +1 −1
  17. arch/riscv/mm/fault.c +1 −1
  18. arch/s390/mm/fault.c +1 −1
  19. arch/sh/mm/fault.c +1 −1
  20. arch/sparc/mm/fault_32.c +2 −2
  21. arch/sparc/mm/fault_64.c +1 −1
  22. arch/um/kernel/trap.c +1 −1
  23. arch/x86/mm/fault.c +1 −1
  24. arch/xtensa/mm/fault.c +1 −1
  25. drivers/iommu/amd/iommu_v2.c +1 −1
  26. drivers/iommu/intel/svm.c +2 −1
  27. include/linux/mm.h +5 −2
  28. mm/gup.c +2 −2
  29. mm/hmm.c +2 −1
  30. mm/ksm.c +2 −1
  31. mm/memory.c +63 −1
arch/alpha/mm/fault.c+1−1
@@ -148,7 +148,7 @@ retry: · 147 unmodified lines
148148 /* If for any reason at all we couldn't handle the fault,
149149 make sure we exit gracefully rather than endlessly redo
150150 the fault. */
151− fault = handle_mm_fault(vma, address, flags);
151+ fault = handle_mm_fault(vma, address, flags, NULL);
152152
153153 if (fault_signal_pending(fault, regs))
154154 return;
arch/arc/mm/fault.c+1−1
@@ -130,7 +130,7 @@ retry: · 129 unmodified lines
130130 goto bad_area;
131131 }
132132
133− fault = handle_mm_fault(vma, address, flags);
133+ fault = handle_mm_fault(vma, address, flags, NULL);
134134
135135 /* Quick path to respond to signals */
136136 if (fault_signal_pending(fault, regs)) {
arch/arm/mm/fault.c+1−1
@@ -224,7 +224,7 @@ good_area: · 223 unmodified lines
224224 goto out;
225225 }
226226
227− return handle_mm_fault(vma, addr & PAGE_MASK, flags);
227+ return handle_mm_fault(vma, addr & PAGE_MASK, flags, NULL);
228228
229229 check_stack:
230230 /* Don't allow expansion below FIRST_USER_ADDRESS */
arch/arm64/mm/fault.c+1−1
@@ -428,7 +428,7 @@ static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr, · 427 unmodified lines
428428 */
429429 if (!(vma->vm_flags & vm_flags))
430430 return VM_FAULT_BADACCESS;
431− return handle_mm_fault(vma, addr & PAGE_MASK, mm_flags);
431+ return handle_mm_fault(vma, addr & PAGE_MASK, mm_flags, NULL);
432432 }
433433
434434 static bool is_el0_instruction_abort(unsigned int esr)
arch/csky/mm/fault.c+2−1
@@ -150,7 +150,8 @@ good_area: · 149 unmodified lines
150150 * make sure we exit gracefully rather than endlessly redo
151151 * the fault.
152152 */
153− fault = handle_mm_fault(vma, address, write ? FAULT_FLAG_WRITE : 0);
153+ fault = handle_mm_fault(vma, address, write ? FAULT_FLAG_WRITE : 0,
154+ NULL);
154155 if (unlikely(fault & VM_FAULT_ERROR)) {
155156 if (fault & VM_FAULT_OOM)
156157 goto out_of_memory;
arch/hexagon/mm/vm_fault.c+1−1
@@ -88,7 +88,7 @@ good_area: · 87 unmodified lines
8888 break;
8989 }
9090
91− fault = handle_mm_fault(vma, address, flags);
91+ fault = handle_mm_fault(vma, address, flags, NULL);
9292
9393 if (fault_signal_pending(fault, regs))
9494 return;
arch/ia64/mm/fault.c+1−1
@@ -143,7 +143,7 @@ retry: · 142 unmodified lines
143143 * sure we exit gracefully rather than endlessly redo the
144144 * fault.
145145 */
146− fault = handle_mm_fault(vma, address, flags);
146+ fault = handle_mm_fault(vma, address, flags, NULL);
147147
148148 if (fault_signal_pending(fault, regs))
149149 return;
arch/m68k/mm/fault.c+1−1
@@ -134,7 +134,7 @@ good_area: · 133 unmodified lines
134134 * the fault.
135135 */
136136
137− fault = handle_mm_fault(vma, address, flags);
137+ fault = handle_mm_fault(vma, address, flags, NULL);
138138 pr_debug("handle_mm_fault returns %x\n", fault);
139139
140140 if (fault_signal_pending(fault, regs))
arch/microblaze/mm/fault.c+1−1
@@ -214,7 +214,7 @@ good_area: · 213 unmodified lines
214214 * make sure we exit gracefully rather than endlessly redo
215215 * the fault.
216216 */
217− fault = handle_mm_fault(vma, address, flags);
217+ fault = handle_mm_fault(vma, address, flags, NULL);
218218
219219 if (fault_signal_pending(fault, regs))
220220 return;
arch/mips/mm/fault.c+1−1
@@ -152,7 +152,7 @@ good_area: · 151 unmodified lines
152152 * make sure we exit gracefully rather than endlessly redo
153153 * the fault.
154154 */
155− fault = handle_mm_fault(vma, address, flags);
155+ fault = handle_mm_fault(vma, address, flags, NULL);
156156
157157 if (fault_signal_pending(fault, regs))
158158 return;
arch/nds32/mm/fault.c+1−1
@@ -206,7 +206,7 @@ good_area: · 205 unmodified lines
206206 * the fault.
207207 */
208208
209− fault = handle_mm_fault(vma, addr, flags);
209+ fault = handle_mm_fault(vma, addr, flags, NULL);
210210
211211 /*
212212 * If we need to retry but a fatal signal is pending, handle the
arch/nios2/mm/fault.c+1−1
@@ -131,7 +131,7 @@ good_area: · 130 unmodified lines
131131 * make sure we exit gracefully rather than endlessly redo
132132 * the fault.
133133 */
134− fault = handle_mm_fault(vma, address, flags);
134+ fault = handle_mm_fault(vma, address, flags, NULL);
135135
136136 if (fault_signal_pending(fault, regs))
137137 return;
arch/openrisc/mm/fault.c+1−1
@@ -159,7 +159,7 @@ good_area: · 158 unmodified lines
159159 * the fault.
160160 */
161161
162− fault = handle_mm_fault(vma, address, flags);
162+ fault = handle_mm_fault(vma, address, flags, NULL);
163163
164164 if (fault_signal_pending(fault, regs))
165165 return;
arch/parisc/mm/fault.c+1−1
@@ -302,7 +302,7 @@ good_area: · 301 unmodified lines
302302 * fault.
303303 */
304304
305− fault = handle_mm_fault(vma, address, flags);
305+ fault = handle_mm_fault(vma, address, flags, NULL);
306306
307307 if (fault_signal_pending(fault, regs))
308308 return;
arch/powerpc/mm/copro_fault.c+1−1
@@ -64,7 +64,7 @@ int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea, · 63 unmodified lines
6464 }
6565
6666 ret = 0;
67− *flt = handle_mm_fault(vma, ea, is_write ? FAULT_FLAG_WRITE : 0);
67+ *flt = handle_mm_fault(vma, ea, is_write ? FAULT_FLAG_WRITE : 0, NULL);
6868 if (unlikely(*flt & VM_FAULT_ERROR)) {
6969 if (*flt & VM_FAULT_OOM) {
7070 ret = -ENOMEM;
arch/powerpc/mm/fault.c+1−1
@@ -511,7 +511,7 @@ retry: · 510 unmodified lines
511511 * make sure we exit gracefully rather than endlessly redo
512512 * the fault.
513513 */
514− fault = handle_mm_fault(vma, address, flags);
514+ fault = handle_mm_fault(vma, address, flags, NULL);
515515
516516 major |= fault & VM_FAULT_MAJOR;
517517
arch/riscv/mm/fault.c+1−1
@@ -109,7 +109,7 @@ good_area: · 108 unmodified lines
109109 * make sure we exit gracefully rather than endlessly redo
110110 * the fault.
111111 */
112− fault = handle_mm_fault(vma, addr, flags);
112+ fault = handle_mm_fault(vma, addr, flags, NULL);
113113
114114 /*
115115 * If we need to retry but a fatal signal is pending, handle the
arch/s390/mm/fault.c+1−1
@@ -476,7 +476,7 @@ retry: · 475 unmodified lines
476476 * make sure we exit gracefully rather than endlessly redo
477477 * the fault.
478478 */
479− fault = handle_mm_fault(vma, address, flags);
479+ fault = handle_mm_fault(vma, address, flags, NULL);
480480 if (fault_signal_pending(fault, regs)) {
481481 fault = VM_FAULT_SIGNAL;
482482 if (flags & FAULT_FLAG_RETRY_NOWAIT)
arch/sh/mm/fault.c+1−1
@@ -482,7 +482,7 @@ good_area: · 481 unmodified lines
482482 * make sure we exit gracefully rather than endlessly redo
483483 * the fault.
484484 */
485− fault = handle_mm_fault(vma, address, flags);
485+ fault = handle_mm_fault(vma, address, flags, NULL);
486486
487487 if (unlikely(fault & (VM_FAULT_RETRY | VM_FAULT_ERROR)))
488488 if (mm_fault_error(regs, error_code, address, fault))
arch/sparc/mm/fault_32.c+2−2
@@ -234,7 +234,7 @@ good_area: · 233 unmodified lines
234234 * make sure we exit gracefully rather than endlessly redo
235235 * the fault.
236236 */
237− fault = handle_mm_fault(vma, address, flags);
237+ fault = handle_mm_fault(vma, address, flags, NULL);
238238
239239 if (fault_signal_pending(fault, regs))
240240 return;
@@ -410,7 +410,7 @@ good_area: · 169 unmodified lines
410410 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
411411 goto bad_area;
412412 }
413− switch (handle_mm_fault(vma, address, flags)) {
413+ switch (handle_mm_fault(vma, address, flags, NULL)) {
414414 case VM_FAULT_SIGBUS:
415415 case VM_FAULT_OOM:
416416 goto do_sigbus;
arch/sparc/mm/fault_64.c+1−1
@@ -422,7 +422,7 @@ good_area: · 421 unmodified lines
422422 goto bad_area;
423423 }
424424
425− fault = handle_mm_fault(vma, address, flags);
425+ fault = handle_mm_fault(vma, address, flags, NULL);
426426
427427 if (fault_signal_pending(fault, regs))
428428 goto exit_exception;
arch/um/kernel/trap.c+1−1
@@ -71,7 +71,7 @@ good_area: · 70 unmodified lines
7171 do {
7272 vm_fault_t fault;
7373
74− fault = handle_mm_fault(vma, address, flags);
74+ fault = handle_mm_fault(vma, address, flags, NULL);
7575
7676 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
7777 goto out_nosemaphore;
arch/x86/mm/fault.c+1−1
@@ -1291,7 +1291,7 @@ good_area: · 1290 unmodified lines
12911291 * userland). The return to userland is identified whenever
12921292 * FAULT_FLAG_USER|FAULT_FLAG_KILLABLE are both set in flags.
12931293 */
1294− fault = handle_mm_fault(vma, address, flags);
1294+ fault = handle_mm_fault(vma, address, flags, NULL);
12951295 major |= fault & VM_FAULT_MAJOR;
12961296
12971297 /* Quick path to respond to signals */
arch/xtensa/mm/fault.c+1−1
@@ -107,7 +107,7 @@ good_area: · 106 unmodified lines
107107 * make sure we exit gracefully rather than endlessly redo
108108 * the fault.
109109 */
110− fault = handle_mm_fault(vma, address, flags);
110+ fault = handle_mm_fault(vma, address, flags, NULL);
111111
112112 if (fault_signal_pending(fault, regs))
113113 return;
drivers/iommu/amd/iommu_v2.c+1−1
@@ -495,7 +495,7 @@ static void do_fault(struct work_struct *work) · 494 unmodified lines
495495 if (access_error(vma, fault))
496496 goto out;
497497
498− ret = handle_mm_fault(vma, address, flags);
498+ ret = handle_mm_fault(vma, address, flags, NULL);
499499 out:
500500 mmap_read_unlock(mm);
501501
drivers/iommu/intel/svm.c+2−1
@@ -872,7 +872,8 @@ static irqreturn_t prq_event_thread(int irq, void *d) · 871 unmodified lines
872872 goto invalid;
873873
874874 ret = handle_mm_fault(vma, address,
875− req->wr_req ? FAULT_FLAG_WRITE : 0);
875+ req->wr_req ? FAULT_FLAG_WRITE : 0,
876+ NULL);
876877 if (ret & VM_FAULT_ERROR)
877878 goto invalid;
878879
include/linux/mm.h+5−2
@@ -38,6 +38,7 @@ struct file_ra_state; · 37 unmodified lines
3838 struct user_struct;
3939 struct writeback_control;
4040 struct bdi_writeback;
41+struct pt_regs;
4142
4243 void init_mm_internals(void);
4344
@@ -1658,7 +1659,8 @@ int invalidate_inode_page(struct page *page); · 1614 unmodified lines
16581659
16591660 #ifdef CONFIG_MMU
16601661 extern vm_fault_t handle_mm_fault(struct vm_area_struct *vma,
1661− unsigned long address, unsigned int flags);
1662+ unsigned long address, unsigned int flags,
1663+ struct pt_regs *regs);
16621664 extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
16631665 unsigned long address, unsigned int fault_flags,
16641666 bool *unlocked);
@@ -1668,7 +1670,8 @@ void unmap_mapping_range(struct address_space *mapping, · 3 unmodified lines
16681670 loff_t const holebegin, loff_t const holelen, int even_cows);
16691671 #else
16701672 static inline vm_fault_t handle_mm_fault(struct vm_area_struct *vma,
1671− unsigned long address, unsigned int flags)
1673+ unsigned long address, unsigned int flags,
1674+ struct pt_regs *regs)
16721675 {
16731676 /* should never happen if there's no MMU */
16741677 BUG();
mm/gup.c+2−2
@@ -884,7 +884,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, · 883 unmodified lines
884884 fault_flags |= FAULT_FLAG_TRIED;
885885 }
886886
887− ret = handle_mm_fault(vma, address, fault_flags);
887+ ret = handle_mm_fault(vma, address, fault_flags, NULL);
888888 if (ret & VM_FAULT_ERROR) {
889889 int err = vm_fault_to_errno(ret, *flags);
890890
@@ -1238,7 +1238,7 @@ retry: · 347 unmodified lines
12381238 fatal_signal_pending(current))
12391239 return -EINTR;
12401240
1241− ret = handle_mm_fault(vma, address, fault_flags);
1241+ ret = handle_mm_fault(vma, address, fault_flags, NULL);
12421242 major |= ret & VM_FAULT_MAJOR;
12431243 if (ret & VM_FAULT_ERROR) {
12441244 int err = vm_fault_to_errno(ret, 0);
mm/hmm.c+2−1
@@ -75,7 +75,8 @@ static int hmm_vma_fault(unsigned long addr, unsigned long end, · 74 unmodified lines
7575 }
7676
7777 for (; addr < end; addr += PAGE_SIZE)
78− if (handle_mm_fault(vma, addr, fault_flags) & VM_FAULT_ERROR)
78+ if (handle_mm_fault(vma, addr, fault_flags, NULL) &
79+ VM_FAULT_ERROR)
7980 return -EFAULT;
8081 return -EBUSY;
8182 }
mm/ksm.c+2−1
@@ -480,7 +480,8 @@ static int break_ksm(struct vm_area_struct *vma, unsigned long addr) · 479 unmodified lines
480480 break;
481481 if (PageKsm(page))
482482 ret = handle_mm_fault(vma, addr,
483− FAULT_FLAG_WRITE | FAULT_FLAG_REMOTE);
483+ FAULT_FLAG_WRITE | FAULT_FLAG_REMOTE,
484+ NULL);
484485 else
485486 ret = VM_FAULT_WRITE;
486487 put_page(page);
mm/memory.c+63−1
@@ -71,6 +71,8 @@ · 70 unmodified lines
7171 #include <linux/dax.h>
7272 #include <linux/oom.h>
7373 #include <linux/numa.h>
74+#include <linux/perf_event.h>
75+#include <linux/ptrace.h>
7476
7577 #include <trace/events/kmem.h>
7678
@@ -4356,6 +4358,64 @@ retry_pud: · 4279 unmodified lines
43564358 return handle_pte_fault(&vmf);
43574359 }
43584360
4361+/**
4362+ * mm_account_fault - Do page fault accountings
4363+ *
4364+ * @regs: the pt_regs struct pointer. When set to NULL, will skip accounting
4365+ * of perf event counters, but we'll still do the per-task accounting to
4366+ * the task who triggered this page fault.
4367+ * @address: the faulted address.
4368+ * @flags: the fault flags.
4369+ * @ret: the fault retcode.
4370+ *
4371+ * This will take care of most of the page fault accountings. Meanwhile, it
4372+ * will also include the PERF_COUNT_SW_PAGE_FAULTS_[MAJ|MIN] perf counter
4373+ * updates. However note that the handling of PERF_COUNT_SW_PAGE_FAULTS should
4374+ * still be in per-arch page fault handlers at the entry of page fault.
4375+ */
4376+static inline void mm_account_fault(struct pt_regs *regs,
4377+ unsigned long address, unsigned int flags,
4378+ vm_fault_t ret)
4379+{
4380+ bool major;
4381+
4382+ /*
4383+ * We don't do accounting for some specific faults:
4384+ *
4385+ * - Unsuccessful faults (e.g. when the address wasn't valid). That
4386+ * includes arch_vma_access_permitted() failing before reaching here.
4387+ * So this is not a "this many hardware page faults" counter. We
4388+ * should use the hw profiling for that.
4389+ *
4390+ * - Incomplete faults (VM_FAULT_RETRY). They will only be counted
4391+ * once they're completed.
4392+ */
4393+ if (ret & (VM_FAULT_ERROR | VM_FAULT_RETRY))
4394+ return;
4395+
4396+ /*
4397+ * We define the fault as a major fault when the final successful fault
4398+ * is VM_FAULT_MAJOR, or if it retried (which implies that we couldn't
4399+ * handle it immediately previously).
4400+ */
4401+ major = (ret & VM_FAULT_MAJOR) || (flags & FAULT_FLAG_TRIED);
4402+
4403+ /*
4404+ * If the fault is done for GUP, regs will be NULL, and we will skip
4405+ * the fault accounting.
4406+ */
4407+ if (!regs)
4408+ return;
4409+
4410+ if (major) {
4411+ current->maj_flt++;
4412+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
4413+ } else {
4414+ current->min_flt++;
4415+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
4416+ }
4417+}
4418+
43594419 /*
43604420 * By the time we get here, we already hold the mm semaphore
43614421 *
@@ -4363,7 +4423,7 @@ retry_pud: · 1 unmodified line
43634423 * return value. See filemap_fault() and __lock_page_or_retry().
43644424 */
43654425 vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
4366− unsigned int flags)
4426+ unsigned int flags, struct pt_regs *regs)
43674427 {
43684428 vm_fault_t ret;
43694429
@@ -4404,6 +4464,8 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address, · 34 unmodified lines
44044464 mem_cgroup_oom_synchronize(false);
44054465 }
44064466
4467+ mm_account_fault(regs, address, flags, ret);
4468+
44074469 return ret;
44084470 }
44094471 EXPORT_SYMBOL_GPL(handle_mm_fault);