[RFC,01/11] XArray: add cmpxchg order test

Message ID 20231028211518.3424020-2-da.gomez@samsung.com
State New
Headers
Series shmem: high order folios support in write path |

Commit Message

Daniel Gomez Oct. 28, 2023, 9:15 p.m. UTC
  XArray multi-index entries do not keep track of the order stored once
the entry is being marked as used (replaced with NULL). Add a test
to check the order is actually lost.

Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
---
 lib/test_xarray.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
  

Comments

Matthew Wilcox Oct. 29, 2023, 8:11 p.m. UTC | #1
On Sat, Oct 28, 2023 at 09:15:35PM +0000, Daniel Gomez wrote:
> +static noinline void check_cmpxchg_order(struct xarray *xa)
> +{
> +	void *FIVE = xa_mk_value(5);
> +	unsigned int order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 15 : 1;

... have you tried this with CONFIG_XARRAY_MULTI deselected?
I suspect it will BUG() because orders greater than 0 are not allowed.

> +	XA_BUG_ON(xa, !xa_empty(xa));
> +	XA_BUG_ON(xa, xa_store_index(xa, 5, GFP_KERNEL) != NULL);
> +	XA_BUG_ON(xa, xa_insert(xa, 5, FIVE, GFP_KERNEL) != -EBUSY);
> +	XA_BUG_ON(xa, xa_store_order(xa, 5, order, FIVE, GFP_KERNEL));
> +	XA_BUG_ON(xa, xa_get_order(xa, 5) != order);
> +	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(FIVE)) != order);
> +	old = xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL);
> +	XA_BUG_ON(xa, old != FIVE);
> +	XA_BUG_ON(xa, xa_get_order(xa, 5) != 0);
> +	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(FIVE)) != 0);
> +	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(old)) != 0);
> +	XA_BUG_ON(xa, !xa_empty(xa));

I'm not sure this is a great test.  It definitely does do what you claim
it will, but for example, it's possible that we might keep that
information for other orders.  So maybe we should have another entry at
(1 << order) that keeps the node around and could theoretically keep
the order information around for the now-NULL entry?
  
Daniel Gomez Nov. 3, 2023, 11:12 p.m. UTC | #2
On Sun, Oct 29, 2023 at 08:11:32PM +0000, Matthew Wilcox wrote:
> On Sat, Oct 28, 2023 at 09:15:35PM +0000, Daniel Gomez wrote:
> > +static noinline void check_cmpxchg_order(struct xarray *xa)
> > +{
> > +	void *FIVE = xa_mk_value(5);
> > +	unsigned int order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 15 : 1;
>
> ... have you tried this with CONFIG_XARRAY_MULTI deselected?
> I suspect it will BUG() because orders greater than 0 are not allowed.
>
> > +	XA_BUG_ON(xa, !xa_empty(xa));
> > +	XA_BUG_ON(xa, xa_store_index(xa, 5, GFP_KERNEL) != NULL);
> > +	XA_BUG_ON(xa, xa_insert(xa, 5, FIVE, GFP_KERNEL) != -EBUSY);
> > +	XA_BUG_ON(xa, xa_store_order(xa, 5, order, FIVE, GFP_KERNEL));
> > +	XA_BUG_ON(xa, xa_get_order(xa, 5) != order);
> > +	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(FIVE)) != order);
> > +	old = xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL);
> > +	XA_BUG_ON(xa, old != FIVE);
> > +	XA_BUG_ON(xa, xa_get_order(xa, 5) != 0);
> > +	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(FIVE)) != 0);
> > +	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(old)) != 0);
> > +	XA_BUG_ON(xa, !xa_empty(xa));
>
> I'm not sure this is a great test.  It definitely does do what you claim
> it will, but for example, it's possible that we might keep that
> information for other orders.  So maybe we should have another entry at
> (1 << order) that keeps the node around and could theoretically keep
> the order information around for the now-NULL entry?

Thanks Matthew for the review. I'm sending a separate patch with the
fixes and improvements on the XArray cmpxchg test.
  

Patch

diff --git a/lib/test_xarray.c b/lib/test_xarray.c
index e77d4856442c..6c22588963bc 100644
--- a/lib/test_xarray.c
+++ b/lib/test_xarray.c
@@ -423,6 +423,26 @@  static noinline void check_cmpxchg(struct xarray *xa)
 	XA_BUG_ON(xa, !xa_empty(xa));
 }
 
+static noinline void check_cmpxchg_order(struct xarray *xa)
+{
+	void *FIVE = xa_mk_value(5);
+	unsigned int order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 15 : 1;
+	void *old;
+
+	XA_BUG_ON(xa, !xa_empty(xa));
+	XA_BUG_ON(xa, xa_store_index(xa, 5, GFP_KERNEL) != NULL);
+	XA_BUG_ON(xa, xa_insert(xa, 5, FIVE, GFP_KERNEL) != -EBUSY);
+	XA_BUG_ON(xa, xa_store_order(xa, 5, order, FIVE, GFP_KERNEL));
+	XA_BUG_ON(xa, xa_get_order(xa, 5) != order);
+	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(FIVE)) != order);
+	old = xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL);
+	XA_BUG_ON(xa, old != FIVE);
+	XA_BUG_ON(xa, xa_get_order(xa, 5) != 0);
+	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(FIVE)) != 0);
+	XA_BUG_ON(xa, xa_get_order(xa, xa_to_value(old)) != 0);
+	XA_BUG_ON(xa, !xa_empty(xa));
+}
+
 static noinline void check_reserve(struct xarray *xa)
 {
 	void *entry;
@@ -1801,6 +1821,7 @@  static int xarray_checks(void)
 	check_xas_erase(&array);
 	check_insert(&array);
 	check_cmpxchg(&array);
+	check_cmpxchg_order(&array);
 	check_reserve(&array);
 	check_reserve(&xa0);
 	check_multi_store(&array);