XArray: set the marks correctly when splitting an entry
If we created a new node to replace an entry which had search marks set,
we were setting the search mark on every entry in that node. That works
fine when we're splitting to order 0, but when splitting to a larger
order, we must not set the search marks on the sibling entries.
Link: https://lkml.kernel.org/r/20240501153120.4094530-1-willy@infradead.org
Fixes: c010d47f10 ("mm: thp: split huge page to any lower order pages")
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reported-by: Luis Chamberlain <mcgrof@kernel.org>
Link: https://lore.kernel.org/r/ZjFGCOYk3FK_zVy3@bombadil.infradead.org
Tested-by: Luis Chamberlain <mcgrof@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
48f044a784
commit
2a0774c288
+13
-1
@@ -1788,9 +1788,11 @@ static void check_split_1(struct xarray *xa, unsigned long index,
|
||||
unsigned int order, unsigned int new_order)
|
||||
{
|
||||
XA_STATE_ORDER(xas, xa, index, new_order);
|
||||
unsigned int i;
|
||||
unsigned int i, found;
|
||||
void *entry;
|
||||
|
||||
xa_store_order(xa, index, order, xa, GFP_KERNEL);
|
||||
xa_set_mark(xa, index, XA_MARK_1);
|
||||
|
||||
xas_split_alloc(&xas, xa, order, GFP_KERNEL);
|
||||
xas_lock(&xas);
|
||||
@@ -1807,6 +1809,16 @@ static void check_split_1(struct xarray *xa, unsigned long index,
|
||||
xa_set_mark(xa, index, XA_MARK_0);
|
||||
XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0));
|
||||
|
||||
xas_set_order(&xas, index, 0);
|
||||
found = 0;
|
||||
rcu_read_lock();
|
||||
xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_1) {
|
||||
found++;
|
||||
XA_BUG_ON(xa, xa_is_internal(entry));
|
||||
}
|
||||
rcu_read_unlock();
|
||||
XA_BUG_ON(xa, found != 1 << (order - new_order));
|
||||
|
||||
xa_destroy(xa);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user