From: "Kiryl Shutsemau (Meta)" <[email protected]>

The mm selftests had two ways to check that a range came out as folios
of a given order.  check_huge_anon() and check_huge_file() counted
folios of the order in the range.  is_range_backed_by_order() checked
each window for a folio with its head at the window start.  Baolin found
the two sets in khugepaged.c confusing [1], and the answer at the time
was to merge them once Yeoreum's rewrite of check_huge_*() on top of
pagemap and kpageflags landed.  It is in mm-new now.

Make check_huge() check windows below the PMD size, route every caller
through it, and make is_range_backed_by_order() an internal of vm_util.c.
The split test's count-based check goes the same way, which also makes
it notice a split at the wrong offset.  On the way check_huge() stops
reopening pagemap and kpageflags on every call, which was the other
reason the separate helper existed.

Yeoreum's HPAGE_SIZE series [2] renames read_pmd_pagesize() to
pmd_psize(); the only overlap is the one call in __check_huge().

Tested on mm-new 2589c5593c20 with KASAN, in 16G guests, x86-64/4K under
KVM and arm64/64K under TCG: the khugepaged matrix at every order,
split_huge_page_test, pagemap_ioctl and khugepaged all:all on tmpfs pass
with the same counts as before.

v2:
 - Drop the PMD size caching from patch 1; Yeoreum's series caches it in
   pmd_psize() (Zi)
 - folio_order_check: skip again when /proc/kpageflags is not readable
   (Sashiko)
 - kpageflags_fd_get(): return early instead of nesting the open

v1: https://lore.kernel.org/all/[email protected]/

[1] 
https://lore.kernel.org/all/[email protected]/
[2] 
https://lore.kernel.org/all/[email protected]/

Kiryl Shutsemau (Meta) (4):
  selftests/mm: open pagemap and kpageflags once for check_huge()
  selftests/mm: check sub-PMD ranges window by window in check_huge()
  selftests/mm: check collapse results through check_huge() only
  selftests/mm: check split results by position, drop
    gather_folio_orders()

 .../testing/selftests/mm/folio_order_check.c  |  29 +-
 tools/testing/selftests/mm/khugepaged.c       |  47 ++-
 .../selftests/mm/khugepaged_sync_check.c      |   7 +-
 .../selftests/mm/split_huge_page_test.c       | 104 +++---
 tools/testing/selftests/mm/vm_util.c          | 314 ++++++------------
 tools/testing/selftests/mm/vm_util.h          |   7 +-
 6 files changed, 173 insertions(+), 335 deletions(-)

Range-diff against v1:
1:  887d475288bf ! 1:  058de2172bde selftests/mm: open pagemap and kpageflags 
once for check_huge()
    @@ Commit message
         selftests/mm: open pagemap and kpageflags once for check_huge()
     
         check_huge_anon() and check_huge_file() open /proc/self/pagemap and
    -    /proc/kpageflags on every call and read the PMD size from sysfs on top.
    -    The khugepaged test calls them hundreds of times.
    +    /proc/kpageflags on every call.  The khugepaged test calls them 
hundreds
    +    of times.
     
         Open both once and keep the descriptors.  A pagemap descriptor is tied
         to the mm of the process that opened it, and the khugepaged fork() 
cases
         call check_huge() from the child, so reopen it when getpid() changes.
     
    -    Cache the PMD size in read_pmd_pagesize() as well.
    -
         Assisted-by: LLM
         Signed-off-by: Kiryl Shutsemau (Meta) <[email protected]>
     
    @@ tools/testing/selftests/mm/vm_util.c
     +{
     +  static int fd = -1;
     +
    -+  if (fd < 0) {
    -+          fd = open(KPAGEFLAGS_PATH, O_RDONLY);
    -+          if (fd < 0)
    -+                  ksft_exit_fail_msg("open kpageflags fail\n");
    -+  }
    ++  if (fd >= 0)
    ++          return fd;
    ++
    ++  fd = open(KPAGEFLAGS_PATH, O_RDONLY);
    ++  if (fd < 0)
    ++          ksft_exit_fail_msg("open kpageflags fail\n");
     +
     +  return fd;
     +}
    @@ tools/testing/selftests/mm/vm_util.c
      uint64_t pagemap_get_entry(int fd, char *start)
      {
        const unsigned long pfn = (unsigned long)start / getpagesize();
    -@@ tools/testing/selftests/mm/vm_util.c: bool check_for_pattern(FILE *fp, 
const char *pattern, char *buf, size_t len)
    - 
    - uint64_t read_pmd_pagesize(void)
    - {
    -+  static uint64_t pmd_pagesize;
    -   int fd;
    -   char buf[20];
    -   ssize_t num_read;
    - 
    -+  if (pmd_pagesize)
    -+          return pmd_pagesize;
    -+
    -   fd = open(PMD_SIZE_FILE_PATH, O_RDONLY);
    -   if (fd == -1)
    -           return 0;
    -@@ tools/testing/selftests/mm/vm_util.c: uint64_t read_pmd_pagesize(void)
    -   buf[num_read] = '\0';
    -   close(fd);
    - 
    --  return strtoul(buf, NULL, 10);
    -+  pmd_pagesize = strtoul(buf, NULL, 10);
    -+  return pmd_pagesize;
    - }
    - 
    - unsigned long rss_anon(void)
     @@ tools/testing/selftests/mm/vm_util.c: static bool 
check_huge_type(uint64_t categories, enum check_huge_type type)
      static bool __check_huge(void *addr, size_t len, int nr_hpages,
                uint64_t hpage_size, enum check_huge_type type)
2:  e89550a21307 = 2:  a95eb5e9e2c8 selftests/mm: check sub-PMD ranges window 
by window in check_huge()
3:  3988e8ff5c3b ! 3:  40aa2e377b65 selftests/mm: check collapse results 
through check_huge() only
    @@ tools/testing/selftests/mm/folio_order_check.c: int main(void)
     -  kpageflags_fd = open("/proc/kpageflags", O_RDONLY);
     -  if (kpageflags_fd < 0)
     -          ksft_exit_skip("open(/proc/kpageflags) requires root\n");
    --
    ++  if (access("/proc/kpageflags", R_OK))
    ++          ksft_exit_skip("/proc/kpageflags requires root\n");
    + 
        orders = thp_supported_orders();
        if (!orders)
    -           ksft_exit_skip("No supported THP orders\n");
     
      ## tools/testing/selftests/mm/khugepaged.c ##
     @@ tools/testing/selftests/mm/khugepaged.c: static int collapse_order;
4:  898256c09252 = 4:  405414814409 selftests/mm: check split results by 
position, drop gather_folio_orders()

base-commit: 2589c5593c200e5146db848730baa1d7dd0c9f4e
-- 
2.54.0


Reply via email to