]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/huge_memory: add folio_split() to debugfs testing interface
authorZi Yan <ziy@nvidia.com>
Wed, 26 Feb 2025 21:00:29 +0000 (16:00 -0500)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 28 Feb 2025 01:00:19 +0000 (17:00 -0800)
This allows to test folio_split() by specifying an additional in folio
page offset parameter to split_huge_page debugfs interface.

Link: https://lkml.kernel.org/r/20250226210032.2044041-7-ziy@nvidia.com
Signed-off-by: Zi Yan <ziy@nvidia.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Kirill A. Shuemov <kirill.shutemov@linux.intel.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Kairui Song <kasong@tencent.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/huge_memory.c

index e7e50b2b23f658dc151f5ccae6703ab53f726df8..6298be12e843898e08052947839f6fd26923cf7d 100644 (file)
@@ -4312,7 +4312,8 @@ static inline bool vma_not_suitable_for_thp_split(struct vm_area_struct *vma)
 }
 
 static int split_huge_pages_pid(int pid, unsigned long vaddr_start,
-                               unsigned long vaddr_end, unsigned int new_order)
+                               unsigned long vaddr_end, unsigned int new_order,
+                               long in_folio_offset)
 {
        int ret = 0;
        struct task_struct *task;
@@ -4396,8 +4397,16 @@ static int split_huge_pages_pid(int pid, unsigned long vaddr_start,
                if (!folio_test_anon(folio) && folio->mapping != mapping)
                        goto unlock;
 
-               if (!split_folio_to_order(folio, target_order))
-                       split++;
+               if (in_folio_offset < 0 ||
+                   in_folio_offset >= folio_nr_pages(folio)) {
+                       if (!split_folio_to_order(folio, target_order))
+                               split++;
+               } else {
+                       struct page *split_at = folio_page(folio,
+                                                          in_folio_offset);
+                       if (!folio_split(folio, target_order, split_at, NULL))
+                               split++;
+               }
 
 unlock:
 
@@ -4420,7 +4429,8 @@ out:
 }
 
 static int split_huge_pages_in_file(const char *file_path, pgoff_t off_start,
-                               pgoff_t off_end, unsigned int new_order)
+                               pgoff_t off_end, unsigned int new_order,
+                               long in_folio_offset)
 {
        struct filename *file;
        struct file *candidate;
@@ -4469,8 +4479,15 @@ static int split_huge_pages_in_file(const char *file_path, pgoff_t off_start,
                if (folio->mapping != mapping)
                        goto unlock;
 
-               if (!split_folio_to_order(folio, target_order))
-                       split++;
+               if (in_folio_offset < 0 || in_folio_offset >= nr_pages) {
+                       if (!split_folio_to_order(folio, target_order))
+                               split++;
+               } else {
+                       struct page *split_at = folio_page(folio,
+                                                          in_folio_offset);
+                       if (!folio_split(folio, target_order, split_at, NULL))
+                               split++;
+               }
 
 unlock:
                folio_unlock(folio);
@@ -4503,6 +4520,7 @@ static ssize_t split_huge_pages_write(struct file *file, const char __user *buf,
        int pid;
        unsigned long vaddr_start, vaddr_end;
        unsigned int new_order = 0;
+       long in_folio_offset = -1;
 
        ret = mutex_lock_interruptible(&split_debug_mutex);
        if (ret)
@@ -4531,30 +4549,33 @@ static ssize_t split_huge_pages_write(struct file *file, const char __user *buf,
                        goto out;
                }
 
-               ret = sscanf(tok_buf, "0x%lx,0x%lx,%d", &off_start,
-                           &off_end, &new_order);
-               if (ret != 2 && ret != 3) {
+               ret = sscanf(tok_buf, "0x%lx,0x%lx,%d,%ld", &off_start, &off_end,
+                               &new_order, &in_folio_offset);
+               if (ret != 2 && ret != 3 && ret != 4) {
                        ret = -EINVAL;
                        goto out;
                }
-               ret = split_huge_pages_in_file(file_path, off_start, off_end, new_order);
+               ret = split_huge_pages_in_file(file_path, off_start, off_end,
+                               new_order, in_folio_offset);
                if (!ret)
                        ret = input_len;
 
                goto out;
        }
 
-       ret = sscanf(input_buf, "%d,0x%lx,0x%lx,%d", &pid, &vaddr_start, &vaddr_end, &new_order);
+       ret = sscanf(input_buf, "%d,0x%lx,0x%lx,%d,%ld", &pid, &vaddr_start,
+                       &vaddr_end, &new_order, &in_folio_offset);
        if (ret == 1 && pid == 1) {
                split_huge_pages_all();
                ret = strlen(input_buf);
                goto out;
-       } else if (ret != 3 && ret != 4) {
+       } else if (ret != 3 && ret != 4 && ret != 5) {
                ret = -EINVAL;
                goto out;
        }
 
-       ret = split_huge_pages_pid(pid, vaddr_start, vaddr_end, new_order);
+       ret = split_huge_pages_pid(pid, vaddr_start, vaddr_end, new_order,
+                       in_folio_offset);
        if (!ret)
                ret = strlen(input_buf);
 out: