mm, thp: track fallbacks due to failed memcg charges separately
authorDavid Rientjes <rientjes@google.com>
Tue, 7 Apr 2020 03:04:28 +0000 (20:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 Apr 2020 17:43:38 +0000 (10:43 -0700)
The thp_fault_fallback and thp_file_fallback vmstats are incremented if
either the hugepage allocation fails through the page allocator or the
hugepage charge fails through mem cgroup.

This patch leaves this field untouched but adds two new fields,
thp_{fault,file}_fallback_charge, which is incremented only when the mem
cgroup charge fails.

This distinguishes between attempted hugepage allocations that fail due to
fragmentation (or low memory conditions) and those that fail due to mem
cgroup limits.  That can be used to determine the impact of fragmentation
on the system by excluding faults that failed due to memcg usage.

Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Yang Shi <yang.shi@linux.alibaba.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Mike Rapoport <rppt@linux.ibm.com>
Cc: Jeremy Cline <jcline@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Link: http://lkml.kernel.org/r/alpine.DEB.2.21.2003061422070.7412@chino.kir.corp.google.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/admin-guide/mm/transhuge.rst
include/linux/vm_event_item.h
mm/huge_memory.c
mm/shmem.c
mm/vmstat.c

index f79ebbcd672509084bd59621a0888c57cf60c6ba..2f31de8f7c749ec70a8e6e33fc7b779276410e26 100644 (file)
@@ -310,6 +310,11 @@ thp_fault_fallback
        is incremented if a page fault fails to allocate
        a huge page and instead falls back to using small pages.
 
+thp_fault_fallback_charge
+       is incremented if a page fault fails to charge a huge page and
+       instead falls back to using small pages even though the
+       allocation was successful.
+
 thp_collapse_alloc_failed
        is incremented if khugepaged found a range
        of pages that should be collapsed into one huge page but failed
@@ -323,6 +328,11 @@ thp_file_fallback
        is incremented if a file huge page is attempted to be allocated
        but fails and instead falls back to using small pages.
 
+thp_file_fallback_charge
+       is incremented if a file huge page cannot be charged and instead
+       falls back to using small pages even though the allocation was
+       successful.
+
 thp_file_mapped
        is incremented every time a file huge page is mapped into
        user address space.
index 41a4c75687489d8805b5101f2d7de7678c12a3ca..ffef0f279747673f4bf4b89cf84e53a1af945e23 100644 (file)
@@ -73,10 +73,12 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
                THP_FAULT_ALLOC,
                THP_FAULT_FALLBACK,
+               THP_FAULT_FALLBACK_CHARGE,
                THP_COLLAPSE_ALLOC,
                THP_COLLAPSE_ALLOC_FAILED,
                THP_FILE_ALLOC,
                THP_FILE_FALLBACK,
+               THP_FILE_FALLBACK_CHARGE,
                THP_FILE_MAPPED,
                THP_SPLIT_PAGE,
                THP_SPLIT_PAGE_FAILED,
@@ -117,6 +119,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
 #ifndef CONFIG_TRANSPARENT_HUGEPAGE
 #define THP_FILE_ALLOC ({ BUILD_BUG(); 0; })
 #define THP_FILE_FALLBACK ({ BUILD_BUG(); 0; })
+#define THP_FILE_FALLBACK_CHARGE ({ BUILD_BUG(); 0; })
 #define THP_FILE_MAPPED ({ BUILD_BUG(); 0; })
 #endif
 
index 0f9389f9d1f8652b5c50aa97186a36b42b88ccab..0080e8df18ef0b465bb63a75510d54c94adcfc42 100644 (file)
@@ -597,6 +597,7 @@ static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf,
        if (mem_cgroup_try_charge_delay(page, vma->vm_mm, gfp, &memcg, true)) {
                put_page(page);
                count_vm_event(THP_FAULT_FALLBACK);
+               count_vm_event(THP_FAULT_FALLBACK_CHARGE);
                return VM_FAULT_FALLBACK;
        }
 
@@ -1446,6 +1447,7 @@ alloc:
                        put_page(page);
                ret |= VM_FAULT_FALLBACK;
                count_vm_event(THP_FAULT_FALLBACK);
+               count_vm_event(THP_FAULT_FALLBACK_CHARGE);
                goto out;
        }
 
index 8160d0762bf53619dca37e61d0f43dc7c8f2959c..b48ac3806f8fd4533bdd0aecceef4ede4756b3f2 100644 (file)
@@ -1871,8 +1871,10 @@ alloc_nohuge:
        error = mem_cgroup_try_charge_delay(page, charge_mm, gfp, &memcg,
                                            PageTransHuge(page));
        if (error) {
-               if (PageTransHuge(page))
+               if (PageTransHuge(page)) {
                        count_vm_event(THP_FILE_FALLBACK);
+                       count_vm_event(THP_FILE_FALLBACK_CHARGE);
+               }
                goto unacct;
        }
        error = shmem_add_to_page_cache(page, mapping, hindex,
index ebc1dcaa05394943d09c7769830fc6468671cd82..96d21a792b57c35ad59f1f062b7efedf9f59a34c 100644 (file)
@@ -1256,10 +1256,12 @@ const char * const vmstat_text[] = {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
        "thp_fault_alloc",
        "thp_fault_fallback",
+       "thp_fault_fallback_charge",
        "thp_collapse_alloc",
        "thp_collapse_alloc_failed",
        "thp_file_alloc",
        "thp_file_fallback",
+       "thp_file_fallback_charge",
        "thp_file_mapped",
        "thp_split_page",
        "thp_split_page_failed",