On Tue, May 05, 2026 at 01:20:45PM +1200, Tao Liu wrote:
Hi Huang,
On Thu, Mar 19, 2026 at 1:24 AM Huang Shijie <huangsj(a)hygon.cn> wrote:
>
> We may meet a large folio at two cases:
> 1.) when height is 1, the real data layout may looks like this:
> --------------------------------------------
> crash> p *(struct xa_node*)0xffff889883a6a910
> $5 = {
> shift = 0 '\000',
> offset = 0 '\000',
> count = 64 '@',
> nr_values = 0 '\000',
> .................
> slots = { 0xffffea0061d21000, 0x2, 0x2, 0x2,
> 0xffffea0121d85c00, 0x12, 0x12, 0x12,
> 0xffffea0121d9f400, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22,
> 0xffffea0121583800, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42,
> 0xffffea0121833e00, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
0x62,
> 0xffffea0121eb3800, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82,
> 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82,
> 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82,
> 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82,
> 0x82, 0x82, 0x82
> },
> .................
> }
> --------------------------------------------
> The page orders for above folios:
> 0xffffea0061d21000 --> order 2
> 0xffffea0121d85c00 --> order 2
> 0xffffea0121d9f400 --> order 3
> 0xffffea0121583800 --> order 3
> 0xffffea0121833e00 --> order 3
> 0xffffea0121eb3800 --> order 5
>
> 2.) when height is not 1, the real data layout may looks like this:
> --------------------------------------------
> slot: { 0xffff8a2c866b745a, 0xffff8a2c866b16d2, 0xfffff9fcc4ea4000,
0xfffff9fcc4eb9000, ..}
> --------------------------------------------
> The 0xffff8a2c866b745a and 0xffff8a2c866b16d2 is a internal node, not a folio.
> The page orders for above folios:
> 0xfffff9fcc4ea4000 --> order 6
>
> Current code does not work correctly with large folio page cache.
> This patch adds the large folio support with following:
>
> 1.) changed the do_xarray_iter() to detect the order of a folio,
> and skip the proper dummy slots for a large folio.
>
> 2.) updated do_xarray_count/do_xarray_dump/do_xarray_dump_cb
> with correct page number if we meet a large folio.
>
> Signed-off-by: Huang Shijie <huangsj(a)hygon.cn>
> ---
> filesys.c | 25 +++++++++++++++++++++----
> tools.c | 16 +++++++++++++---
> 2 files changed, 34 insertions(+), 7 deletions(-)
>
> diff --git a/filesys.c b/filesys.c
> index 2d3b272..f0ac1bb 100644
> --- a/filesys.c
> +++ b/filesys.c
> @@ -4223,7 +4223,11 @@ static void do_xarray_count(ulong node, ulong slot, const
char *path,
> ulong index, void *private)
> {
> struct do_xarray_info *info = private;
> - info->count++;
> +
> + if (info->type == XARRAY_TYPE_PAGE_CACHE)
> + info->count += 1 << folio_order(slot);
> + else
> + info->count++;
> }
Do you think if it is better to decouple xarray with folio? Because
xarray is a common tool, and folio is a special case/user of xarray,
so to me it is better not to integrate folio specific info into
xarray.
How about the following? (This is just to illustrate my idea, there
must be a better approach.)
struct do_xarray_info {
ulong maxcount;
ulong count;
void *data;
ulong (*update_count)(ulong);
};
void do_xarray_count() {
struct do_xarray_info *info = private;
if (info->update_count) // special case
info->count += info->update_count(slot);
else // default case
info->count++;
}
ulong folio_update_count(ulong slot) {
return 1 << folio_order(slot);
}
and let:
info->update_count = folio_update_count;
during folio initialization.
Same to the following functions.
Okay, I will change the code by following this
way.
Thanks
Huang Shijie