]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/mm: hmm-tests: don't hardcode THP size to 2MB
authorAlistair Popple <apopple@nvidia.com>
Tue, 31 Mar 2026 06:34:44 +0000 (17:34 +1100)
committerAndrew Morton <akpm@linux-foundation.org>
Sat, 18 Apr 2026 07:10:52 +0000 (00:10 -0700)
Several HMM tests hardcode TWOMEG as the THP size. This is wrong on
architectures where the PMD size is not 2MB such as arm64 with 64K base
pages where THP is 512MB. Fix this by using read_pmd_pagesize() from
vm_util instead.

While here also replace the custom file_read_ulong() helper used to
parse the default hugetlbfs page size from /proc/meminfo with the
existing default_huge_page_size() from vm_util.

Link: https://lore.kernel.org/20260331063445.3551404-3-apopple@nvidia.com
Link: https://lore.kernel.org/linux-mm/8bd0396a-8997-4d2e-a13f-5aac033083d7@linux.dev/
Fixes: fee9f6d1b8df ("mm/hmm/test: add selftests for HMM")
Fixes: 519071529d2a ("selftests/mm/hmm-tests: new tests for zone device THP migration")
Signed-off-by: Alistair Popple <apopple@nvidia.com>
Reported-by: Zenghui Yu <zenghui.yu@linux.dev>
Closes: https://lore.kernel.org/linux-mm/8bd0396a-8997-4d2e-a13f-5aac033083d7@linux.dev/
Reviewed-by: Balbir Singh <balbirs@nvidia.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: <stable@vger,kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
tools/testing/selftests/mm/hmm-tests.c

index e8328c89d855ef3051c0596174e7314d8252a6f8..788689497e92a4f6ac72aba854e40f65afd3d129 100644 (file)
@@ -34,6 +34,7 @@
  */
 #include <lib/test_hmm_uapi.h>
 #include <mm/gup_test.h>
+#include <mm/vm_util.h>
 
 struct hmm_buffer {
        void            *ptr;
@@ -548,7 +549,7 @@ TEST_F(hmm, anon_write_child)
 
        for (migrate = 0; migrate < 2; ++migrate) {
                for (use_thp = 0; use_thp < 2; ++use_thp) {
-                       npages = ALIGN(use_thp ? TWOMEG : HMM_BUFFER_SIZE,
+                       npages = ALIGN(use_thp ? read_pmd_pagesize() : HMM_BUFFER_SIZE,
                                       self->page_size) >> self->page_shift;
                        ASSERT_NE(npages, 0);
                        size = npages << self->page_shift;
@@ -728,7 +729,7 @@ TEST_F(hmm, anon_write_huge)
        int *ptr;
        int ret;
 
-       size = 2 * TWOMEG;
+       size = 2 * read_pmd_pagesize();
 
        buffer = malloc(sizeof(*buffer));
        ASSERT_NE(buffer, NULL);
@@ -744,7 +745,7 @@ TEST_F(hmm, anon_write_huge)
                           buffer->fd, 0);
        ASSERT_NE(buffer->ptr, MAP_FAILED);
 
-       size = TWOMEG;
+       size /= 2;
        npages = size >> self->page_shift;
        map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
        ret = madvise(map, size, MADV_HUGEPAGE);
@@ -770,54 +771,6 @@ TEST_F(hmm, anon_write_huge)
        hmm_buffer_free(buffer);
 }
 
-/*
- * Read numeric data from raw and tagged kernel status files.  Used to read
- * /proc and /sys data (without a tag) and from /proc/meminfo (with a tag).
- */
-static long file_read_ulong(char *file, const char *tag)
-{
-       int fd;
-       char buf[2048];
-       int len;
-       char *p, *q;
-       long val;
-
-       fd = open(file, O_RDONLY);
-       if (fd < 0) {
-               /* Error opening the file */
-               return -1;
-       }
-
-       len = read(fd, buf, sizeof(buf));
-       close(fd);
-       if (len < 0) {
-               /* Error in reading the file */
-               return -1;
-       }
-       if (len == sizeof(buf)) {
-               /* Error file is too large */
-               return -1;
-       }
-       buf[len] = '\0';
-
-       /* Search for a tag if provided */
-       if (tag) {
-               p = strstr(buf, tag);
-               if (!p)
-                       return -1; /* looks like the line we want isn't there */
-               p += strlen(tag);
-       } else
-               p = buf;
-
-       val = strtol(p, &q, 0);
-       if (*q != ' ') {
-               /* Error parsing the file */
-               return -1;
-       }
-
-       return val;
-}
-
 /*
  * Write huge TLBFS page.
  */
@@ -826,15 +779,13 @@ TEST_F(hmm, anon_write_hugetlbfs)
        struct hmm_buffer *buffer;
        unsigned long npages;
        unsigned long size;
-       unsigned long default_hsize;
+       unsigned long default_hsize = default_huge_page_size();
        unsigned long i;
        int *ptr;
        int ret;
 
-       default_hsize = file_read_ulong("/proc/meminfo", "Hugepagesize:");
-       if (default_hsize < 0 || default_hsize*1024 < default_hsize)
+       if (!default_hsize)
                SKIP(return, "Huge page size could not be determined");
-       default_hsize = default_hsize*1024; /* KB to B */
 
        size = ALIGN(TWOMEG, default_hsize);
        npages = size >> self->page_shift;
@@ -1606,7 +1557,7 @@ TEST_F(hmm, compound)
        struct hmm_buffer *buffer;
        unsigned long npages;
        unsigned long size;
-       unsigned long default_hsize;
+       unsigned long default_hsize = default_huge_page_size();
        int *ptr;
        unsigned char *m;
        int ret;
@@ -1614,10 +1565,8 @@ TEST_F(hmm, compound)
 
        /* Skip test if we can't allocate a hugetlbfs page. */
 
-       default_hsize = file_read_ulong("/proc/meminfo", "Hugepagesize:");
-       if (default_hsize < 0 || default_hsize*1024 < default_hsize)
+       if (!default_hsize)
                SKIP(return, "Huge page size could not be determined");
-       default_hsize = default_hsize*1024; /* KB to B */
 
        size = ALIGN(TWOMEG, default_hsize);
        npages = size >> self->page_shift;
@@ -2106,7 +2055,7 @@ TEST_F(hmm, migrate_anon_huge_empty)
        int *ptr;
        int ret;
 
-       size = TWOMEG;
+       size = read_pmd_pagesize();
 
        buffer = malloc(sizeof(*buffer));
        ASSERT_NE(buffer, NULL);
@@ -2158,7 +2107,7 @@ TEST_F(hmm, migrate_anon_huge_zero)
        int ret;
        int val;
 
-       size = TWOMEG;
+       size = read_pmd_pagesize();
 
        buffer = malloc(sizeof(*buffer));
        ASSERT_NE(buffer, NULL);
@@ -2221,7 +2170,7 @@ TEST_F(hmm, migrate_anon_huge_free)
        int *ptr;
        int ret;
 
-       size = TWOMEG;
+       size = read_pmd_pagesize();
 
        buffer = malloc(sizeof(*buffer));
        ASSERT_NE(buffer, NULL);
@@ -2280,7 +2229,7 @@ TEST_F(hmm, migrate_anon_huge_fault)
        int *ptr;
        int ret;
 
-       size = TWOMEG;
+       size = read_pmd_pagesize();
 
        buffer = malloc(sizeof(*buffer));
        ASSERT_NE(buffer, NULL);
@@ -2332,7 +2281,7 @@ TEST_F(hmm, migrate_partial_unmap_fault)
 {
        struct hmm_buffer *buffer;
        unsigned long npages;
-       unsigned long size = TWOMEG;
+       unsigned long size = read_pmd_pagesize();
        unsigned long i;
        void *old_ptr;
        void *map;
@@ -2398,7 +2347,7 @@ TEST_F(hmm, migrate_remap_fault)
 {
        struct hmm_buffer *buffer;
        unsigned long npages;
-       unsigned long size = TWOMEG;
+       unsigned long size = read_pmd_pagesize();
        unsigned long i;
        void *old_ptr, *new_ptr = NULL;
        void *map;
@@ -2498,7 +2447,7 @@ TEST_F(hmm, migrate_anon_huge_err)
        int *ptr;
        int ret;
 
-       size = TWOMEG;
+       size = read_pmd_pagesize();
 
        buffer = malloc(sizeof(*buffer));
        ASSERT_NE(buffer, NULL);
@@ -2593,7 +2542,7 @@ TEST_F(hmm, migrate_anon_huge_zero_err)
        int *ptr;
        int ret;
 
-       size = TWOMEG;
+       size = read_pmd_pagesize();
 
        buffer = malloc(sizeof(*buffer));
        ASSERT_NE(buffer, NULL);