alpha: use asm-generic/mmu_context.h for no-op implementations
[linux-2.6-microblaze.git] / lib / test_xarray.c
index bdd4d79..8294f43 100644 (file)
@@ -289,6 +289,27 @@ static noinline void check_xa_mark_2(struct xarray *xa)
        xa_destroy(xa);
 }
 
+static noinline void check_xa_mark_3(struct xarray *xa)
+{
+#ifdef CONFIG_XARRAY_MULTI
+       XA_STATE(xas, xa, 0x41);
+       void *entry;
+       int count = 0;
+
+       xa_store_order(xa, 0x40, 2, xa_mk_index(0x40), GFP_KERNEL);
+       xa_set_mark(xa, 0x41, XA_MARK_0);
+
+       rcu_read_lock();
+       xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0) {
+               count++;
+               XA_BUG_ON(xa, entry != xa_mk_index(0x40));
+       }
+       XA_BUG_ON(xa, count != 1);
+       rcu_read_unlock();
+       xa_destroy(xa);
+#endif
+}
+
 static noinline void check_xa_mark(struct xarray *xa)
 {
        unsigned long index;
@@ -297,6 +318,7 @@ static noinline void check_xa_mark(struct xarray *xa)
                check_xa_mark_1(xa, index);
 
        check_xa_mark_2(xa);
+       check_xa_mark_3(xa);
 }
 
 static noinline void check_xa_shrink(struct xarray *xa)
@@ -393,6 +415,9 @@ static noinline void check_cmpxchg(struct xarray *xa)
        XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, FIVE, LOTS, GFP_KERNEL) != FIVE);
        XA_BUG_ON(xa, xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL) != NULL);
        XA_BUG_ON(xa, xa_cmpxchg(xa, 5, NULL, FIVE, GFP_KERNEL) != NULL);
+       XA_BUG_ON(xa, xa_insert(xa, 5, FIVE, GFP_KERNEL) != -EBUSY);
+       XA_BUG_ON(xa, xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL) != FIVE);
+       XA_BUG_ON(xa, xa_insert(xa, 5, FIVE, GFP_KERNEL) == -EBUSY);
        xa_erase_index(xa, 12345678);
        xa_erase_index(xa, 5);
        XA_BUG_ON(xa, !xa_empty(xa));
@@ -1503,6 +1528,49 @@ static noinline void check_store_range(struct xarray *xa)
        }
 }
 
+#ifdef CONFIG_XARRAY_MULTI
+static void check_split_1(struct xarray *xa, unsigned long index,
+                                                       unsigned int order)
+{
+       XA_STATE(xas, xa, index);
+       void *entry;
+       unsigned int i = 0;
+
+       xa_store_order(xa, index, order, xa, GFP_KERNEL);
+
+       xas_split_alloc(&xas, xa, order, GFP_KERNEL);
+       xas_lock(&xas);
+       xas_split(&xas, xa, order);
+       xas_unlock(&xas);
+
+       xa_for_each(xa, index, entry) {
+               XA_BUG_ON(xa, entry != xa);
+               i++;
+       }
+       XA_BUG_ON(xa, i != 1 << order);
+
+       xa_set_mark(xa, index, XA_MARK_0);
+       XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0));
+
+       xa_destroy(xa);
+}
+
+static noinline void check_split(struct xarray *xa)
+{
+       unsigned int order;
+
+       XA_BUG_ON(xa, !xa_empty(xa));
+
+       for (order = 1; order < 2 * XA_CHUNK_SHIFT; order++) {
+               check_split_1(xa, 0, order);
+               check_split_1(xa, 1UL << order, order);
+               check_split_1(xa, 3UL << order, order);
+       }
+}
+#else
+static void check_split(struct xarray *xa) { }
+#endif
+
 static void check_align_1(struct xarray *xa, char *name)
 {
        int i;
@@ -1575,14 +1643,9 @@ static noinline void shadow_remove(struct xarray *xa)
        xa_lock(xa);
        while ((node = list_first_entry_or_null(&shadow_nodes,
                                        struct xa_node, private_list))) {
-               XA_STATE(xas, node->array, 0);
                XA_BUG_ON(xa, node->array != xa);
                list_del_init(&node->private_list);
-               xas.xa_node = xa_parent_locked(node->array, node);
-               xas.xa_offset = node->offset;
-               xas.xa_shift = node->shift + XA_CHUNK_SHIFT;
-               xas_set_update(&xas, test_update_node);
-               xas_store(&xas, NULL);
+               xa_delete_node(node, test_update_node);
        }
        xa_unlock(xa);
 }
@@ -1729,6 +1792,7 @@ static int xarray_checks(void)
        check_store_range(&array);
        check_store_iter(&array);
        check_align(&xa0);
+       check_split(&array);
 
        check_workingset(&array, 0);
        check_workingset(&array, 64);