| From: Dev Jain <dev.jain@arm.com> |
| Subject: xarray: add a BUG_ON() to ensure caller is not sibling |
| Date: Wed, 4 Jun 2025 09:45:33 +0530 |
| |
| Suppose xas is pointing somewhere near the end of the multi-entry batch. |
| Then it may happen that the computed slot already falls beyond the batch, |
| thus breaking the loop due to !xa_is_sibling(), and computing the wrong |
| order. |
| |
| For example, suppose we have a shift-6 node having an order-9 entry => 8 - |
| 1 = 7 siblings, so assume the slots are at offset 0 till 7 in this node. |
| If xas->xa_offset is 6, then the code will compute order as 1 + |
| xas->xa_node->shift = 7. Therefore, the order computation must start from |
| the beginning of the multi-slot entries, that is, the non-sibling entry. |
| |
| Thus ensure that the caller is aware of this by triggering a BUG when the |
| entry is a sibling entry. Note that this BUG_ON() is only active while |
| running selftests, so there is no overhead in a running kernel. |
| |
| Link: https://lkml.kernel.org/r/20250604041533.91198-1-dev.jain@arm.com |
| Signed-off-by: Dev Jain <dev.jain@arm.com> |
| Acked-by: Zi Yan <ziy@nvidia.com> |
| Cc: "Aneesh Kumar K.V" <aneesh.kumar@kernel.org> |
| Cc: Anshuman Khandual <anshuman.khandual@arm.com> |
| Cc: David Hildenbrand <david@redhat.com> |
| Cc: Matthew Wilcox (Oracle) <willy@infradead.org> |
| Cc: Ryan Roberts <ryan.roberts@arm.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| lib/xarray.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/lib/xarray.c~xarray-add-a-bug_on-to-ensure-caller-is-not-sibling |
| +++ a/lib/xarray.c |
| @@ -1910,6 +1910,7 @@ EXPORT_SYMBOL(xa_store_range); |
| * @xas: XArray operation state. |
| * |
| * Called after xas_load, the xas should not be in an error state. |
| + * The xas should not be pointing to a sibling entry. |
| * |
| * Return: A number between 0 and 63 indicating the order of the entry. |
| */ |
| @@ -1920,6 +1921,8 @@ int xas_get_order(struct xa_state *xas) |
| if (!xas->xa_node) |
| return 0; |
| |
| + XA_NODE_BUG_ON(xas->xa_node, xa_is_sibling(xa_entry(xas->xa, |
| + xas->xa_node, xas->xa_offset))); |
| for (;;) { |
| unsigned int slot = xas->xa_offset + (1 << order); |
| |
| _ |