From: Huang Ying <ying.hu...@intel.com>

2 new /proc/vmstat fields are added, "thp_swapin" and
"thp_swapin_fallback" to count swapin a THP from swap device as a
whole and fallback to normal page swapin.

Signed-off-by: "Huang, Ying" <ying.hu...@intel.com>
Cc: "Kirill A. Shutemov" <kirill.shute...@linux.intel.com>
Cc: Andrea Arcangeli <aarca...@redhat.com>
Cc: Michal Hocko <mho...@suse.com>
Cc: Johannes Weiner <han...@cmpxchg.org>
Cc: Shaohua Li <s...@kernel.org>
Cc: Hugh Dickins <hu...@google.com>
Cc: Minchan Kim <minc...@kernel.org>
Cc: Rik van Riel <r...@redhat.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: Naoya Horiguchi <n-horigu...@ah.jp.nec.com>
Cc: Zi Yan <zi....@cs.rutgers.edu>
---
 include/linux/vm_event_item.h |  2 ++
 mm/huge_memory.c              |  4 +++-
 mm/page_io.c                  | 15 ++++++++++++---
 mm/vmstat.c                   |  2 ++
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 5c7f010676a7..7b438548a78e 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -88,6 +88,8 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
                THP_ZERO_PAGE_ALLOC_FAILED,
                THP_SWPOUT,
                THP_SWPOUT_FALLBACK,
+               THP_SWPIN,
+               THP_SWPIN_FALLBACK,
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
                BALLOON_INFLATE,
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index f9b3bef2d2f4..e4d32384e10b 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1667,8 +1667,10 @@ int do_huge_pmd_swap_page(struct vm_fault *vmf, pmd_t 
orig_pmd)
                                /* swapoff occurs under us */
                                } else if (ret == -EINVAL)
                                        ret = 0;
-                               else
+                               else {
+                                       count_vm_event(THP_SWPIN_FALLBACK);
                                        goto fallback;
+                               }
                        }
                        delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
                        goto out;
diff --git a/mm/page_io.c b/mm/page_io.c
index b41cf9644585..96277058681e 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -347,6 +347,15 @@ int __swap_writepage(struct page *page, struct 
writeback_control *wbc,
        return ret;
 }
 
+static inline void count_swpin_vm_event(struct page *page)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+       if (unlikely(PageTransHuge(page)))
+               count_vm_event(THP_SWPIN);
+#endif
+       count_vm_events(PSWPIN, hpage_nr_pages(page));
+}
+
 int swap_readpage(struct page *page, bool synchronous)
 {
        struct bio *bio;
@@ -370,7 +379,7 @@ int swap_readpage(struct page *page, bool synchronous)
 
                ret = mapping->a_ops->readpage(swap_file, page);
                if (!ret)
-                       count_vm_event(PSWPIN);
+                       count_swpin_vm_event(page);
                return ret;
        }
 
@@ -381,7 +390,7 @@ int swap_readpage(struct page *page, bool synchronous)
                        unlock_page(page);
                }
 
-               count_vm_event(PSWPIN);
+               count_swpin_vm_event(page);
                return 0;
        }
 
@@ -400,7 +409,7 @@ int swap_readpage(struct page *page, bool synchronous)
        get_task_struct(current);
        bio->bi_private = current;
        bio_set_op_attrs(bio, REQ_OP_READ, 0);
-       count_vm_event(PSWPIN);
+       count_swpin_vm_event(page);
        bio_get(bio);
        qc = submit_bio(bio);
        while (synchronous) {
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 536332e988b8..d1cb57d8ec79 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1263,6 +1263,8 @@ const char * const vmstat_text[] = {
        "thp_zero_page_alloc_failed",
        "thp_swpout",
        "thp_swpout_fallback",
+       "thp_swpin",
+       "thp_swpin_fallback",
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
        "balloon_inflate",
-- 
2.17.0

Reply via email to