The patch titled Subject: lib/xarray: introduce a new helper xas_get_order has been added to the -mm mm-unstable branch. Its filename is lib-xarray-introduce-a-new-helper-xas_get_order.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/lib-xarray-introduce-a-new-helper-xas_get_order.patch This patch will later appear in the mm-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Kairui Song <kasong@xxxxxxxxxxx> Subject: lib/xarray: introduce a new helper xas_get_order Date: Tue, 26 Mar 2024 01:14:04 +0800 It can be used after xas_load to check the order of loaded entries. Compared to xa_get_order, it saves an XA_STATE and avoid a rewalk. Also add new test for xas_get_order, to make the test work we have to export xas_get_order with EXPORT_SYMBOL_GPL. Link: https://lkml.kernel.org/r/20240325171405.99971-4-ryncsn@xxxxxxxxx Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx> Cc: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/xarray.h | 6 ++++ lib/test_xarray.c | 32 +++++++++++++++++++++++++ lib/xarray.c | 49 ++++++++++++++++++++++++--------------- 3 files changed, 69 insertions(+), 18 deletions(-) --- a/include/linux/xarray.h~lib-xarray-introduce-a-new-helper-xas_get_order +++ a/include/linux/xarray.h @@ -1548,6 +1548,7 @@ void xas_create_range(struct xa_state *) #ifdef CONFIG_XARRAY_MULTI int xa_get_order(struct xarray *, unsigned long index); +int xas_get_order(struct xa_state *xas); void xas_split(struct xa_state *, void *entry, unsigned int order); void xas_split_alloc(struct xa_state *, void *entry, unsigned int order, gfp_t); #else @@ -1555,6 +1556,11 @@ static inline int xa_get_order(struct xa { return 0; } + +static inline int xas_get_order(struct xa_state *xas) +{ + return 0; +} static inline void xas_split(struct xa_state *xas, void *entry, unsigned int order) --- a/lib/test_xarray.c~lib-xarray-introduce-a-new-helper-xas_get_order +++ a/lib/test_xarray.c @@ -1984,6 +1984,37 @@ static noinline void check_get_order(str } } +static noinline void check_xas_get_order(struct xarray *xa) +{ + XA_STATE(xas, xa, 0); + + unsigned int max_order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 20 : 1; + unsigned int order; + unsigned long i, j; + + for (order = 0; order < max_order; order++) { + for (i = 0; i < 10; i++) { + xas_set_order(&xas, i << order, order); + do { + xas_lock(&xas); + xas_store(&xas, xa_mk_value(i)); + xas_unlock(&xas); + } while (xas_nomem(&xas, GFP_KERNEL)); + + xas_lock(&xas); + for (j = i << order; j < (i + 1) << order; j++) { + xas_set_order(&xas, j, 0); + xas_load(&xas); + XA_BUG_ON(xa, xas_get_order(&xas) != order); + } + xas_unlock(&xas); + + xas_set_order(&xas, i << order, order); + xas_store(&xas, NULL); + } + } +} + static noinline void check_destroy(struct xarray *xa) { unsigned long index; @@ -2035,6 +2066,7 @@ static int xarray_checks(void) check_multi_store(&array); check_multi_store_advanced(&array); check_get_order(&array); + check_xas_get_order(&array); check_xa_alloc(); check_find(&array); check_find_entry(&array); --- a/lib/xarray.c~lib-xarray-introduce-a-new-helper-xas_get_order +++ a/lib/xarray.c @@ -1750,39 +1750,52 @@ unlock: EXPORT_SYMBOL(xa_store_range); /** - * xa_get_order() - Get the order of an entry. - * @xa: XArray. - * @index: Index of the entry. + * xas_get_order() - Get the order of an loaded entry after xas_load. + * @xas: XArray operation state. + * + * Called after xas_load, the xas should not be in an error state. * * Return: A number between 0 and 63 indicating the order of the entry. */ -int xa_get_order(struct xarray *xa, unsigned long index) +int xas_get_order(struct xa_state *xas) { - XA_STATE(xas, xa, index); - void *entry; int order = 0; - rcu_read_lock(); - entry = xas_load(&xas); - - if (!entry) - goto unlock; - - if (!xas.xa_node) - goto unlock; + if (!xas->xa_node) + return 0; for (;;) { - unsigned int slot = xas.xa_offset + (1 << order); + unsigned int slot = xas->xa_offset + (1 << order); if (slot >= XA_CHUNK_SIZE) break; - if (!xa_is_sibling(xas.xa_node->slots[slot])) + if (!xa_is_sibling(xas->xa_node->slots[slot])) break; order++; } - order += xas.xa_node->shift; -unlock: + order += xas->xa_node->shift; + return order; +} +EXPORT_SYMBOL_GPL(xas_get_order); + +/** + * xa_get_order() - Get the order of an entry. + * @xa: XArray. + * @index: Index of the entry. + * + * Return: A number between 0 and 63 indicating the order of the entry. + */ +int xa_get_order(struct xarray *xa, unsigned long index) +{ + XA_STATE(xas, xa, index); + int order = 0; + void *entry; + + rcu_read_lock(); + entry = xas_load(&xas); + if (entry) + order = xas_get_order(&xas); rcu_read_unlock(); return order; _ Patches currently in -mm which might be from kasong@xxxxxxxxxxx are mm-filemap-return-early-if-failed-to-allocate-memory-for-split.patch mm-filemap-clean-up-hugetlb-exclusion-code.patch lib-xarray-introduce-a-new-helper-xas_get_order.patch mm-filemap-optimize-filemap-folio-adding.patch