On 29/10/25 4:04 am, Ackerley Tng wrote: > Hi! > > I'm trying to use multi-index xarrays and I was experimenting with > test_xarray.c. > > I'm trying to use xa_erase() on every index after splitting the entry in the > xarray. (and I commented out every other test case just to focus on this test) > > Should erasing every index within the xarray after splitting be a supported use > case? > > Here's the diff: > > diff --git i/lib/test_xarray.c w/lib/test_xarray.c > index 5ca0aefee9aa5..fe74f44bbbd92 100644 > --- i/lib/test_xarray.c > +++ w/lib/test_xarray.c > @@ -1868,6 +1868,9 @@ static void check_split_1(struct xarray *xa, unsigned long index, > rcu_read_unlock(); > XA_BUG_ON(xa, found != 1 << (order - new_order)); > > + for (i = 0; i < (1 << order); i++) > + xa_erase(xa, index + i); > + > xa_destroy(xa); > } > > And made a call to > > check_split_1(xa, 0, 3, 2); > > Here's the assertion I hit: > > node 0x7c4de89e01c0x offset 0 parent 0x7c4de89e0100x shift 0 count 4 values 254 array 0x55edd2dd8940x list 0x7c4de89e01d8x 0x7c4de89e01d8x marks 0 10 0 > xarray: ../shared/../../../lib/xarray.c:764: update_node: Assertion `!(1)' failed. I changed that function to the following: staticvoidcheck_split_1(structxarray *xa, unsignedlongindex, unsignedintorder, unsignedintnew_order) { XA_STATE_ORDER(xas, xa, index, new_order); unsignedinti; for(i = 0; i < (1<< order); i += (1<< new_order)) xa_store_order(xa, i, new_order, xa, GFP_KERNEL); xas_lock(&xas); for(i = 0; i < (1<< order); i += (1<< new_order)) __xa_store(xa, index + i, xa_mk_index(index + i), 0); xas_unlock(&xas); xa_erase(xa, index); xa_destroy(xa); } and I still hit the assertion. I think the new function is still a valid code sequence - Store multi-indices of new_order, for length = 1 << order. Then, replace those entries with xa_mk_index(index + i). Then erase the first index. > > > I think I've narrowed down the issue to the for (;;) loop in xas_store(), which > I believe isn't counting the `values` to be updated in update_node() correctly. > > Is `values += !xa_is_value(first) - !value;` intended to compute the increase in > number of values with replacement of every slot being iterated by the new entry? > > Why does the computation of `count` involve next and entry, and why does the > computation for `values` only statically depend on the initial value of entry, > and on first instead of next? Yeah there is some issue here only - but the code seems to work, tried a lot of different combinations in my head like throwing out a non-value and putting in a value, then vice-versa, then putting a NULL entry - can't figure out the problem :( > > Thanks, > > > Ackerley >