On Thu, May 14, 2026 at 6:33 PM Huang Shijie <huangsj(a)hygon.cn>
wrote:
>
> The folio_order() has three versions:
> 1.) In verion 1, folio_order() uses page[1].compound_order to
> get the folio order. We use "folio_batch" as the indicator.
>
> Please refer to patch set:
>
https://lore.kernel.org/all/20211208042256.1923824-1-willy@infradead.org/
>
> 2.) In version 2, the following patch introduces _folio_order:
> c3a15bff46cb5149 "mm: reimplement folio_order() and
folio_nr_pages()"
> We use "_folio_order" as the indicator.
>
> Please refer to patch set:
>
https://lore.kernel.org/all/20220808193430.3378317-1-willy@infradead.org/
>
> 3.) In version 3, the following patch replaces the _folio_order with _flags_1:
> ebc1baf5c9b46c22 "mm: free up a word in the first tail page"
> folio_order() uses _flags_1 to get the folio order.
>
> We use "free_huge_folio" as the indicator.
> Please refer to patch set:
>
https://lore.kernel.org/linux-mm/20230816151201.3655946-1-willy@infradead...
> (Note, we do not use the struct modifications within the patch set as the
indicator,
> since they have been removed in later kernel.)
>
> This patch will be used in later patches.
>
> Signed-off-by: Huang Shijie <huangsj(a)hygon.cn>
> ---
> defs.h | 8 ++++++
> memory.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> symbols.c | 6 +++++
> 3 files changed, 94 insertions(+)
>
> diff --git a/defs.h b/defs.h
> index 89044b1..bd996ef 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2291,6 +2291,9 @@ struct offset_table { /* stash of
commonly-used offsets */
> long hrtimer_clock_base_index;
> long klp_patch_list;
> long tk_data_timekeeper;
> + long page_compound_order;
> + long folio__folio_order;
> + long folio__flags_1;
> };
>
> struct size_table { /* stash of commonly-used sizes */
> @@ -2470,6 +2473,9 @@ struct size_table { /* stash of commonly-used sizes
*/
> long cpumask_t;
> long task_struct_exit_state;
> long bpf_ringbuf_map;
> + long page_compound_order;
> + long folio__folio_order;
> + long folio__flags_1;
> };
>
> struct array_table {
> @@ -5998,6 +6004,8 @@ ulong do_xarray(ulong, int, struct list_pair *);
> #define XARRAY_TAG_MASK (3UL)
> #define XARRAY_TAG_INTERNAL (2UL)
>
> +int folio_order(ulong folio);
> +
> int file_dump(ulong, ulong, ulong, int, int);
> #define DUMP_FULL_NAME 0x1
> #define DUMP_INODE_ONLY 0x2
> diff --git a/memory.c b/memory.c
> index 17423a5..3deae36 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -410,6 +410,10 @@ mem_init(void)
> DISPLAY_DEFAULT = (sizeof(long) == 8) ? DISPLAY_64 : DISPLAY_32;
> }
>
> +#define FOLIO_ORDER_V1 1
> +#define FOLIO_ORDER_V2 2
> +#define FOLIO_ORDER_V3 3
> +static int folio_order_version;
>
> /*
> * Stash a few popular offsets and some basic kernel virtual memory
> @@ -547,6 +551,38 @@ vm_init(void)
> MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
> MEMBER_OFFSET_INIT(page_page_type, "page",
"page_type");
>
> + /*
> + * The "folio_batch" was introduced at patch set:
> + *
https://lore.kernel.org/all/20211208042256.1923824-1-willy@infradead.org/
> + * Use it as the indicator for folio_order() version 1.
> + */
> + if (STRUCT_EXISTS("folio_batch"))
> + folio_order_version = FOLIO_ORDER_V1;
> +
> + MEMBER_OFFSET_INIT(page_compound_order, "page",
"compound_order");
> + MEMBER_SIZE_INIT(page_compound_order, "page",
"compound_order");
> +
> + /*
> + * The "_folio_order" was introduced at patch set:
> + *
https://lore.kernel.org/all/20220808193430.3378317-1-willy@infradead.org/
> + * Use it as the indicator for folio_order() version 2.
> + */
> + MEMBER_SIZE_INIT(folio__folio_order, "folio",
"_folio_order");
> + MEMBER_OFFSET_INIT(folio__folio_order, "folio",
"_folio_order");
> + if (VALID_MEMBER(folio__folio_order))
> + folio_order_version = FOLIO_ORDER_V2;
> +
> + /*
> + * The "free_huge_folio()" was introduced at patch set:
> + *
https://lore.kernel.org/linux-mm/20230816151201.3655946-1-willy@infradead...
> + * Use it as the indicator for folio_order() version 3.
> + */
> + MEMBER_OFFSET_INIT(folio__flags_1, "folio",
"_flags_1");
> + MEMBER_SIZE_INIT(folio__flags_1, "folio", "_flags_1");
> + if (kernel_symbol_exists("free_huge_folio") ||
> + THIS_KERNEL_VERSION >= LINUX(6,6,0))
I think the "free_huge_folio" check is enough, THIS_KERNEL_VERSION >=
LINUX(6,6,0) is not needed. Again, we should avoid the macro as much
as possible.
If the "free_huge_folio" is changed in future while the
folio_order()
is still workable, we will lose the indicator for folio_order().
Anyway, if you insist we should not use THIS_KERNEL_VERSION, I am okay.
I can remove it in next version.
Thanks
Huang Shijie