On Wed, Mar 05, 2025 at 01:44:29PM -0500, Zi Yan wrote: > OK, it is probably still caused by the __folio_migrate_mapping() bug, since > writing to sibling entries of a multi-index entry breaks the multi-index entry. > Thank Matthew for doing the experiments. Here's what I did: diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 0e865bab4a10..4f38db416ff6 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c @@ -645,6 +645,26 @@ static noinline void check_multi_store_3(struct xarray *xa, unsigned long index, xa_destroy(xa); } + +static noinline void check_multi_store_4(struct xarray *xa, unsigned long index, + unsigned int order) +{ + XA_STATE(xas, xa, index); + int i; + + xa_store_order(xa, index, order, xa_mk_value(0), GFP_KERNEL); + xa_dump(xa); + + xas_lock(&xas); + for (i = 0; i < (1 << order); i++) { + xas_store(&xas, xa_mk_value(index)); + xas_next(&xas); + } + xas_unlock(&xas); + xa_dump(xa); + + xa_destroy(xa); +} #endif static noinline void check_multi_store(struct xarray *xa) @@ -724,6 +744,7 @@ static noinline void check_multi_store(struct xarray *xa) check_multi_store_3(xa, 0, i); check_multi_store_3(xa, 1UL << i, i); } + check_multi_store_4(xa, 16, 4); #endif } The xa_dump before shows sibling entries: $ ./tools/testing/radix-tree/xarray xarray: 0x55b2335be180x head 0x516004c75b82x flags 0 marks 0 0 0 0-63: node 0x516004c75b80x max 0 parent (nil)x shift 0 count 16 values 16 array 0x55b2335be180x list 0x516004c75b98x 0x516004c75b98x marks 0 0 0 16: value 0 (0x0) [0x1x] 17: sibling (slot 16) 18: sibling (slot 16) 19: sibling (slot 16) [...] And then after shows them turned into normal entries: xarray: 0x55b2335be180x head 0x516004c75b82x flags 0 marks 0 0 0 0-63: node 0x516004c75b80x max 0 parent (nil)x shift 0 count 16 values 31 array 0x55b2335be180x list 0x516004c75b98x 0x516004c75b98x marks 0 0 0 16: value 16 (0x10) [0x21x] 17: value 16 (0x10) [0x21x] 18: value 16 (0x10) [0x21x] 19: value 16 (0x10) [0x21x] so I understand why this took a long time to show up. For most uses, you can't tell the difference between these situations.