Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/huge_memory: introduce enum split_type for clarity

Patch series "mm/huge_memory: Define split_type and consolidate split
support checks", v3.

This two-patch series focuses on improving code clarity and removing
redundancy in the huge memory handling logic related to folio splitting.

The series is based on an original proposal to merge two significantly
identical functions that check folio split support[1]. During this
process, we found an opportunity to improve readability by explicitly
defining the split types.

Patch 1: define split_type and use it
Patch 2: merge uniform_split_supported() and non_uniform_split_supported()


This patch (of 2):

We currently handle two distinct types of large folio splitting:
* uniform split
* non-uniform split

Differentiating between these types using a simple boolean variable is not
obvious and can harm code readability.

This commit introduces enum split_type to explicitly define these two
types. Replacing the existing boolean variable with this enumeration
significantly improves code clarity and expressiveness when dealing with
folio splitting logic.

No functional change is expected.

[akpm@linux-foundation.org: tweak layout, per David]
Link: https://lkml.kernel.org/r/20251106034155.21398-1-richard.weiyang@gmail.com
Link: https://lkml.kernel.org/r/20251106034155.21398-2-richard.weiyang@gmail.com
Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Cc: "David Hildenbrand (Red Hat)" <david@kernel.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Nico Pache <npache@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Wei Yang and committed by
Andrew Morton
c467061f fe9d31fd

+20 -15
+5
include/linux/huge_mm.h
··· 364 364 unsigned long len, unsigned long pgoff, unsigned long flags, 365 365 vm_flags_t vm_flags); 366 366 367 + enum split_type { 368 + SPLIT_TYPE_UNIFORM, 369 + SPLIT_TYPE_NON_UNIFORM, 370 + }; 371 + 367 372 bool can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins); 368 373 int __split_huge_page_to_list_to_order(struct page *page, struct list_head *list, 369 374 unsigned int new_order, bool unmapped);
+15 -15
mm/huge_memory.c
··· 3504 3504 * will be split until its order becomes @new_order. 3505 3505 * @xas: xa_state pointing to folio->mapping->i_pages and locked by caller 3506 3506 * @mapping: @folio->mapping 3507 - * @uniform_split: if the split is uniform or not (buddy allocator like split) 3507 + * @split_type: if the split is uniform or not (buddy allocator like split) 3508 3508 * 3509 3509 * 3510 3510 * 1. uniform split: the given @folio into multiple @new_order small folios, 3511 3511 * where all small folios have the same order. This is done when 3512 - * uniform_split is true. 3512 + * split_type is SPLIT_TYPE_UNIFORM. 3513 3513 * 2. buddy allocator like (non-uniform) split: the given @folio is split into 3514 3514 * half and one of the half (containing the given page) is split into half 3515 3515 * until the given @folio's order becomes @new_order. This is done when 3516 - * uniform_split is false. 3516 + * split_type is SPLIT_TYPE_NON_UNIFORM. 3517 3517 * 3518 3518 * The high level flow for these two methods are: 3519 3519 * ··· 3536 3536 */ 3537 3537 static int __split_unmapped_folio(struct folio *folio, int new_order, 3538 3538 struct page *split_at, struct xa_state *xas, 3539 - struct address_space *mapping, bool uniform_split) 3539 + struct address_space *mapping, enum split_type split_type) 3540 3540 { 3541 3541 const bool is_anon = folio_test_anon(folio); 3542 3542 int old_order = folio_order(folio); 3543 - int start_order = uniform_split ? new_order : old_order - 1; 3543 + int start_order = split_type == SPLIT_TYPE_UNIFORM ? new_order : old_order - 1; 3544 3544 int split_order; 3545 3545 3546 3546 /* ··· 3562 3562 * irq is disabled to allocate enough memory, whereas 3563 3563 * non-uniform split can handle ENOMEM. 3564 3564 */ 3565 - if (uniform_split) 3565 + if (split_type == SPLIT_TYPE_UNIFORM) 3566 3566 xas_split(xas, folio, old_order); 3567 3567 else { 3568 3568 xas_set_order(xas, folio->index, split_order); ··· 3659 3659 * @split_at: a page within the new folio 3660 3660 * @lock_at: a page within @folio to be left locked to caller 3661 3661 * @list: after-split folios will be put on it if non NULL 3662 - * @uniform_split: perform uniform split or not (non-uniform split) 3662 + * @split_type: perform uniform split or not (non-uniform split) 3663 3663 * @unmapped: The pages are already unmapped, they are migration entries. 3664 3664 * 3665 3665 * It calls __split_unmapped_folio() to perform uniform and non-uniform split. ··· 3676 3676 */ 3677 3677 static int __folio_split(struct folio *folio, unsigned int new_order, 3678 3678 struct page *split_at, struct page *lock_at, 3679 - struct list_head *list, bool uniform_split, bool unmapped) 3679 + struct list_head *list, enum split_type split_type, bool unmapped) 3680 3680 { 3681 3681 struct deferred_split *ds_queue = get_deferred_split_queue(folio); 3682 3682 XA_STATE(xas, &folio->mapping->i_pages, folio->index); ··· 3711 3711 if (new_order >= old_order) 3712 3712 return -EINVAL; 3713 3713 3714 - if (uniform_split && !uniform_split_supported(folio, new_order, true)) 3714 + if (split_type == SPLIT_TYPE_UNIFORM && !uniform_split_supported(folio, new_order, true)) 3715 3715 return -EINVAL; 3716 3716 3717 - if (!uniform_split && 3717 + if (split_type == SPLIT_TYPE_NON_UNIFORM && 3718 3718 !non_uniform_split_supported(folio, new_order, true)) 3719 3719 return -EINVAL; 3720 3720 ··· 3764 3764 goto out; 3765 3765 } 3766 3766 3767 - if (uniform_split) { 3767 + if (split_type == SPLIT_TYPE_UNIFORM) { 3768 3768 xas_set_order(&xas, folio->index, new_order); 3769 3769 xas_split_alloc(&xas, folio, old_order, gfp); 3770 3770 if (xas_error(&xas)) { ··· 3869 3869 lruvec = folio_lruvec_lock(folio); 3870 3870 3871 3871 ret = __split_unmapped_folio(folio, new_order, split_at, &xas, 3872 - mapping, uniform_split); 3872 + mapping, split_type); 3873 3873 3874 3874 /* 3875 3875 * Unfreeze after-split folios and put them back to the right ··· 4045 4045 { 4046 4046 struct folio *folio = page_folio(page); 4047 4047 4048 - return __folio_split(folio, new_order, &folio->page, page, list, true, 4049 - unmapped); 4048 + return __folio_split(folio, new_order, &folio->page, page, list, 4049 + SPLIT_TYPE_UNIFORM, unmapped); 4050 4050 } 4051 4051 4052 4052 /** ··· 4077 4077 struct page *split_at, struct list_head *list) 4078 4078 { 4079 4079 return __folio_split(folio, new_order, split_at, &folio->page, list, 4080 - false, false); 4080 + SPLIT_TYPE_NON_UNIFORM, false); 4081 4081 } 4082 4082 4083 4083 int min_order_for_split(struct folio *folio)